您的位置:首页 > 编程语言 > Java开发

java类初始化顺序

2017-07-04 09:40 204 查看
转载请注明出处:http://blog.csdn.net/mr_leixiansheng/article/details/74280154

一个Java类中会定义各种变量、方法和代码块。其中方法和代码块从存在的意义上来讲,都是为了操作这些变量的。所以就笔者个人理解,类的主体该是变量,方法和代码块是为变量而存在的。

变量值的改变有两种情形,一是在进行初始化的时候,而是在方法中对其进行操作的时候。变量值改变的先后顺序将直接影响到程序运行的正确与否,所以理正确理解变量值在Java中如何改变对于一个优秀码农来说,显得尤为重要。就以上两种改变变量值的情形来说,第二种情形比较直观,即方法何时调用,便何时改变相应变量值。当然,其中的特殊方法——构造器除外。构造器可以认为是一种特殊的初始化过程,但由于其特殊性,其初始化过程又必须单独考虑。

本文主要以包括“构造器”在内的一些初始化操作对变量值改变的先后顺序为线索,进行了一些代码实验和思考。

由于该主题的情况较复杂,笔者打算先从几个点出发,讨论变量值改变的先后顺序,最后再将这些点中的情况进行一个统一的讨论。

一、先初始化静态(static)变量,再初始化非静态变量。

其中涉及到类的加载机制,因为静态变量是在类加载的过程中便开辟空间,而非静态变量在实例化对象的时候才会开辟空间,具体代码实验如下:

[java]
view plain
copy

print?

class A  
{  
    int y=printInit("non-static");  
    static int x= printInit("static");  
  
    private static int printInit(String s)  
    {  
        System.out.println(s);  
        return 1;  
    }  
}  
  
  
  
class InitSequStatic   
{  
    public static void main(String[] args)  
    {  
        A a= new A();  
    }  
}  

class A
{
int y=printInit("non-static");
static int x= printInit("static");

private static int printInit(String s)
{
System.out.println(s);
return 1;
}
}

class InitSequStatic
{
public static void main(String[] args)
{
A a= new A();
}
}


其运行结果如下:


可以发现,尽管A类中的非静态变量先于静态变量定义,但在初始化的过程中(准确来说是类的加载和对象的实例化过程中),静态变量先于非静态变量。这一点,我们在类继承中将会理解得更加清楚

二、对于有类继承关系的代码中,先初始化(加载)父类静态变量,然后初始化(加载)子类静态变量,继而初始化父类非静态变量,调用父类构造器,最后初始化子类非静态变量,调用子类构造器。

若存在多重继承关系,也同理。之所以此处静态变量“初始化”后面的括号中有“加载”一词,是因为静态变量在类加载的过程中首先会进行默认初始化,但非静态变量在对象实例化的过程中就不会进行默认初始化。此处需要提及:初始化分为默认初始化、显示初始化、构造代码块初始化和构造函数初始化,这将在第三点“初始化过程”中具体提及。

以下图为例:

先依次初始化(加载)A类、B类和C类的静态变量,再依次初始化A类的非静态变量,调用A类的构造器;然后依次初始化B类的非静态变量,调用B类的构造器;最后依次初始化C类的非静态变量,调用C类的构造器。具体代码实验如下:

[java]
view plain
copy

print?

class A   
{  
    A()  
    {  
        System.out.println("A constructor");  
    }  
    static int ax=printInit("A static");  
  
    int ay=printInit("A nontatic");  
  
    private static int printInit(String s)  
    {  
        System.out.println(s);  
        return 1;  
    }  
}  
 class B extends A  
 {  
     B()  
    {  
        System.out.println("B constructor");  
    }  
    static int bx=printInit("B static");  
  
    int by=printInit("B nontatic");  
  
    private static int printInit(String s)  
    {  
        System.out.println(s);  
        return 1;  
    }  
 }  
  
 class C extends B  
 {  
     C()  
    {  
        System.out.println("C constructor");  
    }  
    static int cx=printInit("C static");  
  
    int cy=printInit("C nontatic");  
  
    private static int printInit(String s)  
    {  
        System.out.println(s);  
        return 1;  
    }  
  
    public static void main(String[] args)  
     {  
        C c=new C();  
    }  
 }  

class A
{
A()
{
System.out.println("A constructor");
}
static int ax=printInit("A static");

int ay=printInit("A nontatic");

private static int printInit(String s)
{
System.out.println(s);
return 1;
}
}
class B extends A
{
B()
{
System.out.println("B constructor");
}
static int bx=printInit("B static");

int by=printInit("B nontatic");

private static int printInit(String s)
{
System.out.println(s);
return 1;
}
}

class C extends B
{
C()
{
System.out.println("C constructor");
}
static int cx=printInit("C static");

int cy=printInit("C nontatic");

private static int printInit(String s)
{
System.out.println(s);
return 1;
}

public static void main(String[] args)
{
C c=new C();
}
}

其运行结果如下:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: