Java中的对象构造与初始化顺序-创新互联

参考文献:

创新互联建站是专业的淄博网站建设公司,淄博接单;提供成都网站设计、网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行淄博网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

Java核心技术卷一
Java程序的初始化顺序
Java 代码块和类的执行调用顺序
类的加载与初始化

域初始化

如果在构造器中没有显式地给域赋予初值,那么就会被自动地赋为默认值: 数值为 0、
布尔值为 false、 对象引用为 null。

也可以直接在实例域中设置一个有意义的初值,在执行构造器之前,先执行赋值操作,将所有类对象的该域设置为一样的值。比如:

class Employee
{private String name ="JXZ";
}
构造器

如果在编写一个类时没有编写构造器, 那么系统就会提供一个无参数构造器。这个构造
器将所有的实例域设置为默认值。

仅当类没有提供任何构造器的时候, 系统才会提供一个默认的构造器。如果类中提供了至少一个构造器, 但是没有提供无参数的构造器, 则在构造对象时如果没有提供参数就会被视为不合法。比如在编写类的时候,已经给出了一个简单的构造器,但是想用new ClassName()构造实例,就必须提供一个默认的构造器(即不带参数的构造器),如果希望所有域被赋予默认值, 可以采用下列格式:

public ClassName(){}

关键字 this 代表引用方法的隐式参数。但其还有一层用法,如果构造器的第一条语句形如this(...)(如果这样使用,也只能放在第一条语句), 这个构造器将调用同一个类的另一个构造器。比如:

public Employee(double s)
{// 这里就会调用Employee(String, double)
this("Employee #" + nextld, s);
nextld++;
}
初始化块

在一个类的声明中,可以包含多个代码块,只要构造类的对象(实例化),这些块就会被执行,在下面有个例子中可以看到,装载类但没有实例化类的时候,这些普通代码块并没有被执行,与之相对的是静态代码块执行了。

class Employee
{private static int nextld;
	private int id;
	private String name;
	private double salary;
	
	// object initialization block
	{id = nextld;
	nextld++;
	}
}

《Java核心技术卷一》中对调用构造器的相关步骤总结如下:

  1. 所有数据域被初始化为默认值(0、false 或 null)
  2. 按照在类声明中出现的次序, 依次执行所有域初始化语句和初始化块
  3. 如果构造器第一行调用了第二个构造器,则执行第二个构造器主体
  4. 执行这个构造器的主体
Java程序的初始化顺序

在加入父子类以及静态代码块后,初始化顺序就复杂一点了,参考Java程序的初始化顺序总结如下:

静态优于非静态,先父后子,域声明优于块,最后构造器

  1. 父类静态变量
  2. 父类静态代码块
  3. 子类静态变量
  4. 子类静态代码块
  5. 父类非静态变量
  6. 父类非静态代码块
  7. 父类构造函数
  8. 子类非静态变量
  9. 子类非静态代码块
  10. 子类构造函数

实例代码:

public class InitOrderDemo {public InitOrderDemo() {System.out.println("父类构造方法");
    }

    String b = "父类非静态变量";

    {System.out.println(b);
        System.out.println("父类非静态代码块");
    }

    static String a = "父类静态变量";

    static {System.out.println(a);
        System.out.println("父类静态代码块");
    }

    public static void superMethod() {System.out.println("父类普通静态方法");
    }
}
public class Derived extends InitOrderDemo {public Derived() {System.out.println("子类构造方法");
    }

    String b = "子类非静态变量";

    {System.out.println(b);
        System.out.println("子类非静态代码块");
    }

    static String a = "子类静态变量";

    static {System.out.println(a);
        System.out.println("子类静态代码块");
    }

    public static void derivedMethod() {System.out.println("子类普通静态方法");
    }

    public static void main(String[] args) {//        InitOrderDemo.superMethod();
        Derived.derivedMethod();
//        new Derived();
    }
}

执行输出如下:

InitOrderDemo.superMethod()
父类静态变量
父类静态代码块
子类静态变量
子类静态代码块
父类普通静态方法

Derived.derivedMethod():
父类静态变量
父类静态代码块
子类静态变量
子类静态代码块
子类普通静态方法

new Derived():
父类静态变量
父类静态代码块
子类静态变量
子类静态代码块
父类非静态变量
父类非静态代码块
父类构造方法
子类非静态变量
子类非静态代码块
子类构造方法

其中InitOrderDemo.superMethod()Derived.derivedMethod()的打印只打印出了静态变量和静态代码块,和装载时域的初始化有关。参考类的加载与初始化

同时参考代码块的两个注意事项:

  1. static代码块即静态代码块,随着类的加载而执行,是对类进行初始化,且只会执行一次,当之后再创建对象时,静态代码块不会再执行。普通代码块每创建一次对象便会执行一次。
  2. 普通代码块,在创建对象实例时,会被默认调用,每当创建一次,便会调用一次。如果只是使用类的静态成员时,普通代码块不会被调用执行。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


分享题目:Java中的对象构造与初始化顺序-创新互联
网址分享:http://hbruida.cn/article/ccohip.html