Thinking in Java笔记之类及对象的初始化
2016-03-13 18:16
579 查看
最近在看《Thinking in Java》这本书,之前一直对类及对象的初始化过程不太清楚,只是感到很模糊。看了这本书关于对象初始化的部分,终于搞明白了。
废话不多说,先上两个例子,实例摘自 《Thinking in Java》。
Test1:
我们将Cups类定义为下面这个,其初始化过程是一样的。即先初始化static成员变量,然后才static代码块。
Test2:
总结:从Test1和Test2,可以看出,首先,加载拥有主方法main的Demo14这个类,可以理解为jvm默认调用加载拥有main方法的Demo14这个类Demo14.class,然后初始化Demo14里的static修饰的成员变量,然后执行static修饰的代码块,然后执行main方法。main方法里(此处有三个出口):
a.若定义一个类(比如Cups x),并new初始化这个对象Cups(),那么jvm就会加载Cups.class,然后初始化static成员变量,然后执行static修饰的代码块,然后非静态成员变量,然后非静态代码块,然后构造器。
b.若直接调用类的静态方法或者静态类的静态成语,比如调用Cups.c1.f(99),那么jvm同样会加载Cups.class这个类,并且初始化。顺序为:初始化static成员变量,然后[b]执行static修饰的代码块,然后非静态成员变量,然后非静态代码块,然后构造器。[/b]
c.若main方法里既没有new对象,也没有调用类的静态成员或静态方法,没有类会被加载,所以没有类会被初始化,没有对象被初始化。
注意:
1.上面的初始化过程,我们假定静态成员,静态代码块,非静态成员,非静态代码块都存在的情况。若某一项不存在,那么顺序是不会变的,我们只需要从这个顺序列表中将其删除就OK。
2.当我们new同一个类(Cups)的多个对象,或者调用Cups的静态方法或者静态成员多次,Cups.class只加载并且初始化一次。也就是说static成员变量和static静态代码块只初始化一次。非静态的对象的非静态成员变量、非静态代码块、构造器初始化次数则和new的次数相等。
3.当我们new了Cups的一个对象,jvm载入Cups.class,并且初始化static修饰的...后,然后会为非静态成员默认初始化值[基本数据类型(int,byte,short,long为0,float,double为0.0,boolean为false,char为''),引用数据类型会将句柄初始化为null],然后若我们显示初始化此成员变量,就会执行显示初始化,然后执行非静态代码块,然后构造器。
废话不多说,先上两个例子,实例摘自 《Thinking in Java》。
Test1:
package com.westward; /** * @desc 《Thinking in Java》 Demo Page 115 * */ public class Demo14 { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("Inside main");//先初始化static成员变量和static代码块,然后非static成员变量和代码块,然后构造器,然后static main方法 Cups.c1.f(99);//1 } /*static Cups x= new Cups(); static Cups y= new Cups();*///2 } class Cup{ public Cup(int marker) { System.out.println("Cup("+marker+")"); } void f(int marker){ System.out.println("f("+marker+")"); } } class Cups{ static Cup c1; static Cup c2; static{ c1= new Cup(1); c2= new Cup(2); } Cups() { System.out.println("Cups()");// TODO Auto-generated constructor stub } } //run as:Cup(1) Cup(2) Cups() Cups() Inside main f(99) //注释掉tag2:Inside main Cup(1) Cup(2) f(99)
我们将Cups类定义为下面这个,其初始化过程是一样的。即先初始化static成员变量,然后才static代码块。
class Cups{ static{ c1= new Cup(1); c2= new Cup(2); } static Cup c1; static Cup c2; Cups() { System.out.println("Cups()");// TODO Auto-generated constructor stub } }
Test2:
package com.westward; /** * @desc 《Thinking in Java》 Demo Page 117 * */ public class Demo15 { Mug c1; Mug c2; { c1= new Mug(1); c2= new Mug(2); System.out.println("c1 & c2 initialized"); } Demo15(){ System.out.println("Mugs()"); } public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("Inside main()"); // Demo15 x= new Demo15();//2 } } class Mug{ Mug(int marker) { System.out.println("Mug("+marker+")"); } void f(int marker){ System.out.println("f("+marker+")"); } } //Inside main() Mug(1) Mug(2) c1 & c2 initialized Mugs() //注释掉tag2: Inside main()
总结:从Test1和Test2,可以看出,首先,加载拥有主方法main的Demo14这个类,可以理解为jvm默认调用加载拥有main方法的Demo14这个类Demo14.class,然后初始化Demo14里的static修饰的成员变量,然后执行static修饰的代码块,然后执行main方法。main方法里(此处有三个出口):
a.若定义一个类(比如Cups x),并new初始化这个对象Cups(),那么jvm就会加载Cups.class,然后初始化static成员变量,然后执行static修饰的代码块,然后非静态成员变量,然后非静态代码块,然后构造器。
b.若直接调用类的静态方法或者静态类的静态成语,比如调用Cups.c1.f(99),那么jvm同样会加载Cups.class这个类,并且初始化。顺序为:初始化static成员变量,然后[b]执行static修饰的代码块,然后非静态成员变量,然后非静态代码块,然后构造器。[/b]
c.若main方法里既没有new对象,也没有调用类的静态成员或静态方法,没有类会被加载,所以没有类会被初始化,没有对象被初始化。
注意:
1.上面的初始化过程,我们假定静态成员,静态代码块,非静态成员,非静态代码块都存在的情况。若某一项不存在,那么顺序是不会变的,我们只需要从这个顺序列表中将其删除就OK。
2.当我们new同一个类(Cups)的多个对象,或者调用Cups的静态方法或者静态成员多次,Cups.class只加载并且初始化一次。也就是说static成员变量和static静态代码块只初始化一次。非静态的对象的非静态成员变量、非静态代码块、构造器初始化次数则和new的次数相等。
3.当我们new了Cups的一个对象,jvm载入Cups.class,并且初始化static修饰的...后,然后会为非静态成员默认初始化值[基本数据类型(int,byte,short,long为0,float,double为0.0,boolean为false,char为''),引用数据类型会将句柄初始化为null],然后若我们显示初始化此成员变量,就会执行显示初始化,然后执行非静态代码块,然后构造器。
相关文章推荐
- 深入分析 Java 中的中文编码问题
- Java程序占用的内存可能会大于Xmx
- Java HashMap的内部实现机制
- 关于springMVC中ModelAndView的问题
- 关于JAVA学习计划和感想
- 设计模式之适配器模式
- ZOJ 3498 Javabeans(数学)
- 本地通过Eclipse链接Hadoop操作Mysql数据库问题小结
- The 8th Zhejiang Provincial Collegiate Programming Contest->L - Javabeans
- java 的堆栈问题
- java的访问控制权限
- LeetCode85 Maximal Rectangle java题解
- Spring MVC 基于Method的映射规则(注解版)
- myeclipse中创建user library
- java基础
- Java集合:TreeMap使用详解及源码分析
- JAVA md5加密的工具类
- Java文件操作源码大全
- java常用集合总结
- java常用集合总结