这里主要学习初始化,分为:

1.变量初始化

2.构造函数初始化

3.数组初始化

4.继承初始化

 

1.变量初始化

成员初始化分为两种:

(1)成员变量初始化

在定义成员变量时,如果没有给变量赋于初始值,系统会给出一个默认值。

这里有两种选择:要么使用系统的默认初始值,要么自己定义初始值。

系统给出的默认输出值为:



boolean    false
char       [ ]
byte       0
short      0
int        0
long       0
float      0.0
double     0.0
refenece   null



char初始值为0,显示为空白;String 引用类型默认初始时为null

(2)局部变量初始化

局部变量在使用“基本类型“时必须富商初始值,否则编译器会报错。

 

2.构造函数初始化

(1)成员变量在任何构造函数调用之前被初始化,如:



class Init2
{
    private int i;
    
    public Init2(int i)
    {
        this.i = i;
    }
    
    public static void main(String[] args)
    {
        new Init2(3);
    }
    
    private String reference;
}



1).i 在构造函数调用之前已经被赋予初始值0,然后才在构造函数中赋于新值3。

2).不管成员变量散落什么地方,都能够首先初始化。

3).变量的定义顺序决定了初始化的顺序。

 

(2)静态数据库的初始化

这里使用“Java编程思想”的例子



class Bowl
{
    public Bowl(int maker)
    {
        // maker用于标记
        System.out.println("Bowl(" + maker +")");
    }
    
    public void f1(int maker)
    {
        System.out.println("f1(" + maker +")");
    }
}

class Table
{
    static Bowl bowl1 = new Bowl(1); // 静态成员变量
    
    public Table()
    {
        System.out.println("Table");
        bowl1.f1(1);
    }
    
    public void f2(int maker)
    {
        System.out.println("f2(" + maker +")");
    }
    
    static Bowl bowl2 = new Bowl(2); // 静态成员变量
}

class Cupboard
{
    Bowl bowl3 = new Bowl(3); // 非静态成员变量
    static Bowl bowl4 = new Bowl(4); // 静态成员变量
    
    public Cupboard()
    {
        System.out.println("Table");
        bowl3.f1(2);
    }
    
    public void f3(int maker)
    {
        System.out.println("f3(" + maker +")");
    }
    
    static Bowl bowl5 = new Bowl(5); // 静态成员变量
}

class Init3
{
    public static void main(String[] args)
    {
        System.out.println("Init3.main()");
        new Cupboard();
        System.out.println("Init3.main()");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
    }
    
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
}



执行结果:



Bowl(1)
Bowl(2)
Table
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard
f1(2)
Init3.main()
Bowl(3)
Cupboard
f1(2)
Init3.main()
Bowl(3)
Cupboard
f1(2)
f2(1)
f3(1)



说明:

第一步:首先初始化 static Table table = new Table(); (因为 在调用 Init3 main有静态变量)

1.1.在Table中初始化 static Bowl bowl1 = new Bowl(1);,此时,输出的结果为:Bowl(1)

1.2.在Table中初始化 static Bowl bowl2 = new Bowl(2);,此时,输出的结果为:Bowl(2)

1.3.初始化Table的构造函数,输出: Table,并执行 bowl1.f1(1) 方法,输出:f1(1)

所以在执行完成 static Table table = new Table(); 后,输出结果为:



Bowl(1)
Bowl(2)
Table
f1(1)



第二步:初始化 static Cupboard cupboard = new Cupboard();

2.1.在Cupboard中初始化 static Bowl bowl4 = new

2.2.在Cupboard中初始化 static Bowl bowl5 = new

2.3.在Cupboard中初始化 Bowl bowl3= new

2.4.初始化Cupboard 的构造函数,输出: Cupboard,并执行 bowl3.f1(2) 方法,输出:f1(2)

所以在执行完成static Cupboard cupboard = new Cupboard();后,输出结果为:



Bowl(4)
Bowl(5)
Bowl(3)
Cupboard
f1(2)



第三步:执行main函数的打印,输出:Init3.main()

第四步:执行 new这里不执行静态成员变量bowl4 和bowl5,是因为已经被初始化,不需要在执行)

4.1.在Cupboard中初始化 Bowl bowl3= new

4.2.初始化Cupboard 的构造函数,输出: Cupboard,并执行 bowl3.f1(2) 方法,输出:f1(2)

输出结果:



Bowl(3)
Cupboard
f1(2)



第五步:执行main函数的打印,输出:Init3.main()

第六步:执行 new这里不执行静态成员变量bowl4 和bowl5,是因为已经被初始化,不需要在执行)

6.1.在Cupboard中初始化 Bowl bowl3= new

6.2.初始化Cupboard 的构造函数,输出: Cupboard,并执行 bowl3.f1(2) 方法,输出:f1(2)

输出结果:



Bowl(3)
Cupboard
f1(2)



第七步:执行 table.f2(1); 输出:f2(1)

第八步:执行cupboard.f3(1); 输出:f3(1)

小节:初始化顺序先是静态对象(前提是该对象没有被初始化),然后是非静态对象。

(3)静态块初始化

在类中使用 static{….} 表示静态块,将在使用该类之前的数据初始化。

静态块与静态变量一样,只初始化一次。并且,执行顺序是按照位置从上往下执行,即:静态块与静态方法优先级相同。

触发条件:

1.首次生成这个类的对象;

2.首次访问属于这个类的静态成员。



class StaticBlock
{
    public static String s = "StaticBlock";
    
    static
    {
        System.out.println("StaticBlock.enclosing_method()");
    }
}

class InvokeStaticBlock
{
    public static void main(String[] args)
    {
        new StaticBlock(); // 生成对象的引用
        String ss = StaticBlock.s; // 使用该对象的静态成员
    }
}



 

总结:

对象创建流程:

1.当创建对象实例时,会去执行构造函数(构造函数可以看成是静态方法),Java解释器必须找到类路径,以定位到该类的.class文件;

2.加载class文件,并初始化所有静态数据。因此,静态初始化只有在class对象首次加载时执行一次,后面再次加载不再执行初始化操作;

3.创建对象时,会在堆上分配足够的存储空间;

4.这块存储空间会被清零,将基本类型数据附上初始值,引用类型置为null;

5.执行所有出现与字段定义处的初始化动作,即如果字段有初始值,即修改默认初始值,赋于新值;

6.执行构造函数。