1. Java初始化顺序
当实例化对象时,对象所在类的所有成员变量首先要进行初始化,只有当所有类成员完成初始化后,才会调用对象所在类的构造函数创建对象。
3个原则:
(1)静态对象(变量)优先于非静态对象(变量)初始化。其中,静态对象(变量) 只初始化一次,而非静态对象(变量)可能会初始化多次。
(2)父类优先于子类进行初始化。
(3)按照成员变量的定义顺序进行初始化。
即便变量定义散布于方法定义之中,她们依然在任何方法(包括构造函数)被调用之前先初始化。
java初始化工作可以在许多不同的代码块中完成(如静态代码块、构造函数等),他们的执行顺序如下:
父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数。
示例:
class B extends Object{
static //父类静态代码块
{
System.out.println("Load B1");
}
public B() //父类构造函数
{
System.out.println("Create B");
}
static //父类静态代码块
{
System.out.println("Load B2");
}
}
class A extends B{
static //子类静态代码块
{
System.out.println("Load A");
}
public A() //子类构造函数
{
System.out.println("Create A");
}
}
public class Testclass{
public static void main(String[] args)
{
new A();
}
}
输出结果:
Load B1
Load B2
Load A
Create B
Create A
2. 构造函数
定义:构造函数是一种特殊的函数,用来在对象实例化时初始化对象的成员变量。
特点:(1) 构造函数必须与类的名字相同,并且不能有返回值(返回值也不能为void)
(2)每个类可以有多个构造函数。当开发人员没有提供构造函数时,编译器在把源代码编译成字节码的过程中会提供一个没有参数默认的构造函数,但该构造函数不会执行任何代码。
(3)构造函数可以有0个、1个或1个以上的参数。
(4)构造函数在对象实例化时被自动调用,且只运行一次;而普通方法是在程序执行到它时被调用,且可以被该对象调用多次
(5)构造函数不能被继承,因此,它不能被覆盖,但是构造函数能够被重载。
(6)当父类没有提供无参数的构造函数时,子类的构造函数中必须显示地调用父类的构造函数(通过super关键字)。
如果父类提供了无参数的构造函数,编译器默认调用父类提供的无参数的构造函数。
当有父类时,在实例化对象时会先执行父类的构造函数,然后执行子类的构造函数。(见上文初始化顺序)
(7)当父类和子类都没有定义构造函数时,编译器会为父类生成一个默认的无参数的构造函数,给子类也生成一个默认的无参数的构造函数。默认构造器的修饰符只跟当前类的修饰符有关(如,一个类被定义为public,那么它的默认构造器也为public)。