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核心技术卷一》中对调用构造器的相关步骤总结如下:
- 所有数据域被初始化为默认值(0、false 或 null)
- 按照在类声明中出现的次序, 依次执行所有域初始化语句和初始化块
- 如果构造器第一行调用了第二个构造器,则执行第二个构造器主体
- 执行这个构造器的主体
在加入父子类以及静态代码块后,初始化顺序就复杂一点了,参考Java程序的初始化顺序总结如下:
静态优于非静态,先父后子,域声明优于块,最后构造器
- 父类静态变量
- 父类静态代码块
- 子类静态变量
- 子类静态代码块
- 父类非静态变量
- 父类非静态代码块
- 父类构造函数
- 子类非静态变量
- 子类非静态代码块
- 子类构造函数
实例代码:
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()
的打印只打印出了静态变量和静态代码块,和装载时域的初始化有关。参考类的加载与初始化
同时参考代码块的两个注意事项:
- static代码块即静态代码块,随着类的加载而执行,是对类进行初始化,且只会执行一次,当之后再创建对象时,静态代码块不会再执行。普通代码块每创建一次对象便会执行一次。
- 普通代码块,在创建对象实例时,会被默认调用,每当创建一次,便会调用一次。如果只是使用类的静态成员时,普通代码块不会被调用执行。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享标题:Java中的对象构造与初始化顺序-创新互联
网站链接:http://azwzsj.com/article/ccohip.html