静态数据的初始化(Think in java P95页代码解析)
2016-02-21 20:12
691 查看
初始化顺序:
先静态对象而后在非静态对象,知道这些还不行,还要知道所有基本类型和对象引用都会在调用构造器或者其他方法之前得到初始化,包括在定义时已经指定初始化的变量,系统仍然会初始化(例如:int i 初始化是0,boolean 初始化是false),知道这些下面的程序就容易理解了:
class Bowl
{
public Bowl(int i)
{
System.out.println("Bolwl (" + i + ")");
}
public void f1(int j)
{
System.out.println("f1(" + j + ")");
}
}
class Table
{
static Bowl bowl = new Bowl(1);
public Table()
{
System.out.println("table ()");
bowl2.f1(1);
}
public void f2(int n)
{
System.out.println("f2 (" + n + ")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard
{
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
public Cupboard()
{
System.out.println("Cupboard()");
bowl4.f1(2);
}
public void f3(int i)
{
System.out.println("f3(" + i + ")");
}
static Bowl bowl5 = new Bowl(5);
}
程序从JtcshTest类开始运行,根据上面的规则,成员变量会在构造方法或其他方法之前得到初始化,
因此运行的时候先执行static Table table = new Table();
static Cupboard cupboard = new Cupboard(); 这两句。
好,我们先看第一个static Table table = new Table(); 这句话,这句是一个静态的一个实例,然后看Table这个类,
Table类里有两个静态变量bowl 和bowl2 (Bowl类不需要解释了就一个有参构造方法和一个普通方法),还有一个无参构造方法和一个普通的方法(f2()),
根据先静态对象而后在非静态对象和成员变量会在构造方法或其他方法之前得到初始化的顺序,
先执行bowl 结果是:Bolwl (1) ,然后在执行bowl2:Bolwl (2),然后在执行table构造函数结果是:table () f1(1),
再看 static Cupboard cupboard = new Cupboard();这句,同上,会先执行bolwl4和bolwl5,然后在执行bolwl3,然后构造方法,
即结果是:
Bolwl (4)
Bolwl (5)
Bolwl (3)
Cupboard()
f1(2)
这时开始执行main方法,
这时结果是:在 main 第一次创建 Cupboard实例
由于静态变量只能初始化一次,也就说,这时就不会再次执行静态应用初始化了。
紧接着结果是:
Bolwl (3)
Cupboard()
f1(2)
然后打印第二个:
在 main 第er次创建 Cupboard实例
Bolwl (3)
Cupboard()
f1(2)
可想而知和第一个一样。
然后就执行table.f2(1);
cupboard.f3(1);这两个,结果是:f2 (1) f3(1)
因此打印的整个结果是:
先静态对象而后在非静态对象,知道这些还不行,还要知道所有基本类型和对象引用都会在调用构造器或者其他方法之前得到初始化,包括在定义时已经指定初始化的变量,系统仍然会初始化(例如:int i 初始化是0,boolean 初始化是false),知道这些下面的程序就容易理解了:
class Bowl
{
public Bowl(int i)
{
System.out.println("Bolwl (" + i + ")");
}
public void f1(int j)
{
System.out.println("f1(" + j + ")");
}
}
class Table
{
static Bowl bowl = new Bowl(1);
public Table()
{
System.out.println("table ()");
bowl2.f1(1);
}
public void f2(int n)
{
System.out.println("f2 (" + n + ")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard
{
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
public Cupboard()
{
System.out.println("Cupboard()");
bowl4.f1(2);
}
public void f3(int i)
{
System.out.println("f3(" + i + ")");
}
static Bowl bowl5 = new Bowl(5);
}
public class JtcshTest { public static void main(String[] args) { System.out.println("在 main 第一次创建 Cupboard实例"); new Cupboard(); System.out.println("在 main 第er次创建 Cupboard实例"); new Cupboard(); table.f2(1); cupboard.f3(1); } static Table table = new Table(); static Cupboard cupboard = new Cupboard(); }
程序从JtcshTest类开始运行,根据上面的规则,成员变量会在构造方法或其他方法之前得到初始化,
因此运行的时候先执行static Table table = new Table();
static Cupboard cupboard = new Cupboard(); 这两句。
好,我们先看第一个static Table table = new Table(); 这句话,这句是一个静态的一个实例,然后看Table这个类,
Table类里有两个静态变量bowl 和bowl2 (Bowl类不需要解释了就一个有参构造方法和一个普通方法),还有一个无参构造方法和一个普通的方法(f2()),
根据先静态对象而后在非静态对象和成员变量会在构造方法或其他方法之前得到初始化的顺序,
先执行bowl 结果是:Bolwl (1) ,然后在执行bowl2:Bolwl (2),然后在执行table构造函数结果是:table () f1(1),
再看 static Cupboard cupboard = new Cupboard();这句,同上,会先执行bolwl4和bolwl5,然后在执行bolwl3,然后构造方法,
即结果是:
Bolwl (4)
Bolwl (5)
Bolwl (3)
Cupboard()
f1(2)
这时开始执行main方法,
这时结果是:在 main 第一次创建 Cupboard实例
由于静态变量只能初始化一次,也就说,这时就不会再次执行静态应用初始化了。
紧接着结果是:
Bolwl (3)
Cupboard()
f1(2)
然后打印第二个:
在 main 第er次创建 Cupboard实例
Bolwl (3)
Cupboard()
f1(2)
可想而知和第一个一样。
然后就执行table.f2(1);
cupboard.f3(1);这两个,结果是:f2 (1) f3(1)
因此打印的整个结果是:
相关文章推荐
- 关于学习Java的心得体会
- No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
- ThreadLocal 对象的使用
- LeetCode22GenerateParentheses--In Java
- 【慕课笔记】第四章 JAVA中的集合框架(上) 第2节 Collection接口&List接口简介
- java中的IO整理
- java中的参数传递问题
- JAVA IO(二)File类详解
- java基础 内部类使用总结
- Eclipse相关问题
- java安全 ——JAAS(Java 认证和授权服务)开发指南
- JAVA学习记录 -- String
- java容器--ArrayList源码简析
- java 之 集合遍历,存储结构,集合特点
- java父子类继承(1)
- 冒泡排序
- spring缓存实现原理
- spring.net的使用
- 二分法查找
- JAVA 读取zip文档方式二:使用 ZipFile