您的位置:首页 > 其它

类成员初始化

2015-12-20 21:39 295 查看
在类内部:初始化的顺序

静态的成员变量;

普通的成员变量;

构造器的调用。

在派生类中:初始化的顺序

调用基类的构造器

按声明顺序调用成员的初始化方法

调用派生类构造器主体

大多数类的初始化都是按照这些顺序结合在一起的。

下面是一个例子:

public class Test extends Sub{
public static int field = getField2();
public Test(){
System.out.println("test()");
}
public static void main(String[] args) {
new Test();
}
public static int getField2(){
System.out.println("test static");
return 1;
}

}
class Super{
public Super(){
System.out.println("super()");
}
public int field = 0;
public static int field2 = getField2();
public void fun1(){
System.out.println("super fun1");
}
public int getField(){
return field;
}
public static void fun2(){
System.out.println("super static fun2");
}
public static int getField2(){
fun2();
return 1;
}
}

class Sub extends Super{
public Sub(){
System.out.println("sub()");
}
public int field = getField();
public static int field2 = getField2();
public void fun1(){
System.out.println("sub fun1");
}
public int getField(){
fun1();
return 1;
}
public static void fun2(){
System.out.println("sub static fun2");
}
public static int getField2(){
fun2();
return 1;
}
}


下面我们看看输出的结果:

output:

super static fun2
sub static fun2
test static
super()
sub fun1
sub()
test()
成功构建 (总时间: 0 秒)


我们在main()方法中调用了new一个test的对象,由于test继承了sub,而sub继承了super。(当进行继承时,我们已经知道基类的一切,并且可以访问基类中任何声明为public和protected的成员。这意味着在派生类中,必须假定基类的所有成员都是有效的。一种标准方法是,构造动作一经发生,那么对象所有部分的全体成员都会得到构建。然而,在构造器内部,我们必须确保所要使用的成员都已经构建完毕。为确保这一目的,唯一的办法就是首先调用基类的构造器。那么在进入派生类构造器时,在基类中可供我们访问的成员都已得到初始化。)

只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。

所以static变量是最先初始化的,并根据基类到派生类的顺序。

当static变量初始化之后,下一个执行的就是基类super的实例变量,然后在轮到super的构造器。

接着就是sub的实例变量和构造器。我们可以看到sub的构造器执行之前有sub fun1的输出。这就证明是先初始化实例变量再执行构造器的。

当基类都初始化完成时,在轮到派生类。

实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。而静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

也就是说实例变量在每个对象的创建都会初始化,而静态变量只会在第一次加载类时初始化(只会初始化一次)。

下面是一个例子:

public class ExplicitStatic {
public static void main(String[] args) {
System.out.println("Inside main()");
Cups.cup1.f(99);
}
static Cups cup1 = new Cups();
static Cups cup2 = new Cups();
}
class Cup {
Cup(int marker) {
System.out.println("Cup("+marker+")");
}
void f(int marker){
System.out.println("f(" + marker + ")");
}
}

class Cups {
static Cup cup1;
static Cup cup2;
public int field = getField();
static {
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups() {
System.out.println("Cups()");
}
public int getField(){
System.out.println("field");
return 1;
}
}


output:

Cup(1)
Cup(2)
field
Cups()
field
Cups()
Inside main()
f(99)
成功构建 (总时间: 1 秒)


根据上面所说的顺序,相信大家都会看得懂的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: