这里主要学习初始化,分为:
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.执行构造函数。