TJI读书笔记07-初始化
Posted 吾码2016
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TJI读书笔记07-初始化相关的知识,希望对你有一定的参考价值。
成员初始化
java尽量去保证每个变量在使用前都会得到初始化.
- 对于方法局部变量,java不会自动初始化他们,如果没有显式的初始化,编译器会报错.
- 对于类的数据成员,java会自动初始化成一个”空”“的值.简单来说,这个空的值对于基本数据类型就是,0,false,和空格. 对于引用类型就是null.
(只是类的数据成员会隐式初始化,这个我之前还真没有太在意,一直以为java默认的初始化是对所有类型的变量都生效的. )
显式初始化就不用说了. 很简单.
构造方法初始化
在构造方法中初始化变量是个很灵活的办法.但是,成员变量的隐式初始化是不会被阻止的.
public class Counter{
int i;
Counter(){
i=7;
}
}
这段代码,i会先被初始化为0,然后在构造方法中在被初始化为7;
初始化块
- static关键字不能作用于局部变量.
- 无论创建多少个对象,静态数据在内存中只占用一份存储区域.(static修饰的玩意儿都是属于类而不是属于实例的.)
- static修饰的成员变量会被自动初始化为”空”.
一码解千愁,把这段代码放到eclipse中debug一下,就全明白了.
class Bowl{
Bowl(int marker){
System.out.println("Bowl("+marker+")");
}
public void f1(int marker){
System.out.println("f1("+marker+")");
}
}
class Table{
static Bowl bowl1 = new Bowl(1);
Table(){
System.out.println("Table()");
bowl2.f1(1);
}
void f2(int marker){
System.out.println("f2("+marker+")");
}
static Bowl bowl2 = new Bowl(2);
}
class CupBoard{
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
CupBoard() {
System.out.println("CupBoard()");
bowl4.f1(2);
}
void f3(int marker){
System.out.println("f3("+marker+")");
}
static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
public static void main(String[] args) {
System.out.println("Create new CupBoard() in main");
new CupBoard();
System.out.println("Create new CupBoard() in 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)
Create new CupBoard() in main
Bowl(3)
CupBoard()
f1(2)
Create new CupBoard() in main
Bowl(3)
CupBoard()
f1(2)
f2(1)
f3(1)
*/
- static成员变量初始化会在所有语句之前执行,并且只执行一次
- 非static成员变量初始化紧随static成员变量初始化语句之后,每次加载类的时候都会执行
- 成员变量初始化之后,执行构造函数
- 构造函数执行完,才回再去执行其他函数.
埃大爷的总结显得更高端:
假设有一个Dog类
- 即使没有显式的static关键字,构造器实际上也是一个static方法.首次创建Dog类的对象的时候,或者Dog类的静态方法,静态字段首次被访问的时候,java解释器会查找类的路径,定位Dog.class文件
- 然后装载class文件,有关静态初始化的所有动作在这个时候就会执行. 因此,静态初始化只在类首次加载的时候执行一次
- 当new Dog()的时候,先在堆上分配为Dog对象分配足够的空间
- 然后这块空间清零,这就将Dog对象中的所有基本类型数据都设置成了”空”值
- 执行所有字段定义处的初始化动作
- 执行构造器
所有的成员变量初始化的语句都可以看作一个只有一条语句的初始化块. 那么带static关键字的可以看作静态初始化块,不带static关键字的,可以看作非静态初始化块.
static{
int i=0;
}
{
int j=0;
}
做个反向推论,既然单条语句的特殊的初始化块适用于埃大爷的原则,那么普通的初始化块也适用这个原则(这是多么无耻不负责任的推论…)
初始化的顺序
初始化顺序其实在上面都说完了. 为什么是这样的埃大爷也解释了. 小白总结就是:
- 默认的初始化
- 显式初始化语句和初始化块
- 构造器中
- 通过方法的赋值
按照埃大爷的解释,那静态初始化实在类装载的时候,而默认的初始化实在为实例分配空间的时候,那静态初始化块应该是早于默认初始化的. 不确定对不对,先记者,回头看到了再说.
以上是关于TJI读书笔记07-初始化的主要内容,如果未能解决你的问题,请参考以下文章