Java中对象构造

一个类中,对象构造时的构造过程

顺序如下:

1、变量定义时给出初始值,则先获得初始值。

2、调用构造块

3、调用相应的构造函数

非final成员没有在上述任何地方赋值,则获得相应类型的默认值。

先来看一个类中,初始化时,各个构造方法的调用顺序

下面是一个例子

public class Main
{

    public static void main(String[] args)
    {

        Base b = new Base();

        System.out.println("Base中baseVal的最终值为:"+b.baseVal);    

         /*          baseVal=11          baseVal=12          Base中baseVal的最终值为:12       */

    }

}

class Base
{

    public int baseVal = 10;    // ①

    {                           // ②构造块
        baseVal = 11;
        System.out.println("baseVal=" + baseVal);
    }

    public Base()              // ③
    {
        baseVal = 12;
        System.out.println("baseVal=" + baseVal);
    }

}

一个继承链中,对象构造时的过程

1、java中,子类的构造函数,如果你不显式用super写出来的话,默认会调用父类的默认构造函数。

你可以通过super 显式指定调用父类的哪个构造函数。需要注意的是:这个super调用必须是子类构造函数的第一条语句

下面是例子。

我们不为字段的初始值编号了,而只为初始化块和构造函数编号。

可以发现:构造一个子类,会先去调用父类的整套构造机制(注意:我并没有这样说:构造一个子类,会先去构造一个父类,原因待会解释),父类又会调用父类的父类的构造机制,.......一直带到Object为止。那么,这就会引发一条调用链,过程有点类似递归,只有高层的函数调用完了,底层的函数才会执行完。

public class Main
{

    public static void main(String[] args)
    {

        SubClass sub = new SubClass();

        /*
         * console:
         *                  ①baseVal=11
                            ②baseVal=12
                            ③baseVal=12 sub Val=91
                            ④baseVal=12 sub Val=92
         */

    }

}

class Base
{

    public int baseVal = 10;    

    {
        baseVal = 11;
        System.out.println("①baseVal=" + baseVal);
    }

    public Base()
    {
        baseVal = 12;
        System.out.println("②baseVal=" + baseVal);
    }

}

class SubClass extends Base
{
     public int subVal = 90;

    {
        subVal = 91;
        System.out.println("③baseVal="+baseVal+" sub Val=" + subVal);

    }

    public SubClass()
    {
        // super() //子类构造函数默认隐式调用父类的默认构造函数 ,当然你也可以显示调用
        subVal = 92;

        System.out.println("④baseVal="+baseVal+" sub Val=" + subVal);
    }

}

子类的构造,会生成一个父类对象吗?

我不知道那些说:构造子类时,会先去构造一个父类对象,他们说的这个过程,到底是怎样一个模型。
这个问题的关键在于:是生成的一个内嵌的父类,还是生成一个独立的父类。

显然,我认为是生成的是内嵌的父类,即子类包含父类的数据,父类并不是独立存在的。

试想一下:如果new一个子类对象,会生成一个独立的父类,那么,对于深层次的继承链。比如10层,new一个最高层子类,岂不是会在内存生成 10个对象,显然是不可以的,不高效的。

那么子类对象在构造时,为什么要调用父类地方构造 函数呢?那是因为,子类要借用父类的构造函数类构造自己。因为子类包含父类的数据。

写在最后的总结

1、java 中的对象都在堆中生成,而引用他们的引用变量则视情况而定。比如一个类对象中有一个String成员,变量名为name,那么name也在堆中。C++中,如果使用new,则对象生成在堆中,如果不用new,一般在栈中。

2、类的成员变量如果不显式初始化,则赋值为默认值。但最好明确地个一个初始值。

3、构造函数可以重载。

4、如果自定义类不给出构造函数,那么会获得一个默认的无参的构造函数。如果手动提供了自定义的构造函数,则系统不会提供默认的无参构造函数,如果你需要无参的构造函数,你应该自己添加。

5、final成员变量必须在new对象时被初始化,包括定义final变量时给初始值,或者在初始化块中,或者在构造函数中。

6、静态构造块的语句会在类第一次被加载时执行,当你使用类时,这个过程就完成了。

时间: 2024-10-11 12:46:03

Java中对象构造的相关文章

java中对象的初始化过程

class Parent{ int num = 8;// ->3 Parent(){ //super(); // ->2 //显示初始化 // ->3 //构造代码段 // ->4 show(); // ->5 } {// ->4 System.out.println("Parent constructor code run->"); } public void show(){//被覆盖 System.out.println("num

java中c#中statc 静态调用不同之处、c#的静态构造函数和java中的构造代码块、静态代码块

1.java和c#静态成员调用的不同之处 static 表示静态的,也就是共享资源,它是在类加载的时候就创建了 java中   可以通过实例来调用,也可以通过类名.成员名来调用,但是一般最好使用类名.成员这个方式,因为静态成员是属于类的,并不是属于具体的对象 c#中     只能通过类名.成员调用,并不能 用实例来进行调用 2.c#的静态构造函数和java中的构造代码块.静态代码块 c# 静态构造函数的特点:        1)静态构造函数不需要手动调用,系统自动调用        2)静态构造

java中的构造块、静态块等说明

一:这篇博客写的时候我在学校已经一个星期了,为什么又会想到写这le,因为这几天又在重新学下有关spring.myBatis的知识,其中在实例化sessionFactory的时候用到了静态块,虽然在学习Hibernate时也用到过,那时候没现在想的深入.所以就回过头来记载下吧. 最近自己突然觉得做网页好没意思啊,强烈的感觉啊,现在觉得去学习android和ios很好,因为觉得做网页都是那几个框架,一成不变啊,写来写去都是这么做.看来自己在程序这方面做不久啊. 二:先说说静态块: static{ S

Java中对象、对象引用、堆、栈、值传递以及引用传递的详细解释

Java中对象.对象引用.堆.栈.值传递以及引用传递的详细解释 1.对象和对象引用的区别: (1).对象: 万物皆对象.对象是类的实例.在Java中new是用来在堆上创建对象用的.一个对象可以被多个引用所指向. (2).对象引用: 类似于C++中的地址.通过对象引用可以找到对象.一个引用可以指向多个对象.操纵的标识符实际上是指向对象的引用. 就像:对象存放在屋子里,对象的引用就相当于屋子的钥匙. 2.值传递和引用传递的区别: (1).值传递:传递的是值的拷贝.也就是说传递后就不互相关了. (2)

java中对象多态时成员变量,普通成员函数及静态成员函数的调用情况

/* 样例1: class Parent{ int num = 3; } class Child extends Parent{ int num = 4; } */ /* 样例2: class Parent{ } class Child extends Parent{ int num = 4; } */ /* 样例3: class Parent{ void show(){ System.out.println("Parent Show!"); } } class Child exten

Java之对象构造过程

先来运行一段代码 class A { public A() { init(); } public void init() { } public static void main(String[] args) { B b = new B(); System.out.println("终于i的值为:" + b.i + ",j的值为:" + b.j); } } class B extends A { int i; int j = 999; public void init

java中对象的初始化问题

最近又把java编程思想看了看.又有些收获.此书确实不错 java中的初始化相信很多人都知道.但是具体的初始化步骤,初始化几次确不一定.上代码 public class A{ public static A a = new A(); public static int i; public static int j= 2; public A(){ i++; j++; } public static void main(String[] args){ A a1= new A(); System.ou

java中对象转json,json转list,json转map

在IDEA中的springboot项目里写的一个测试例子,新建User类,四个字段,Long id , String password,String userName,int age; 以及带参构造,toString方法 在pom.xml中添加 net.sf.json-lib  依赖: 1 <!-- 对象转json依赖包 --> 2 <!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib --> 3 <

面试题:Java中对象序列化接口(Serializable)的意义

Serializable接口是一个里面什么都没有的接口 它的源代码是public interface Serializable{},即什么都没有. 如果一个接口里面什么内容都没有,那么这个接口是一个标识接口,比如,一个学生遇到一个问题,排错排了几天也没解决,此时,她举手了(示意我去帮他解决),然后我过去,帮他解决了,那么这个举手其实就是一个标识,自己不能解决的问题标示我去帮他解决,在Java中的这个Serializable接口是给JVM看的,告诉JVM,我不做这个类的序列化了,你(JVM)给我序