本文在“针对类(Class)和抽象类(Abstract Class)(即不包括接口(Interface),枚举(Enum),注解(Annotation)),且不存在继承关系”的背景下进行介绍。
一、初始化 1.1、实例对象和类对象初始化 1.1.1、实例对象初始化 实例对象的字段(即普通字段)按照如下顺序进行初始化:
1 2 3 4 1、默认初始化 2、定义初始化 3、实例初始化语句初始化 4、构造器初始化 
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package  chapter5;public  class  InitialOrder  {     int  i  =  f(10 );   {     System.out.println("定义初始化后 i:"  + i);          i = 20 ;     System.out.println("实例初始化语句初始化后 i:"  + i);   }   public  InitialOrder ()  {          i = 30 ;     System.out.println("构造器初始化后 i:"  + i);   }   public  static  void  main (String[] args)  {     new  InitialOrder ();   }   public  int  f (int  a)  {     System.out.println("默认初始化后 i:"  + i);     return  10 ;   } } 
触发条件:实例对象的创建。需要注意的是:1)实例对象初始化中“默认初始化”和“构造器初始化”初始化阶段必存在,“定义初始化”和“实例初始化语句初始化”初始化阶段可选存在;2)实例对象初始化中初始化阶段之间连续不间断。
1.1.2、类对象初始化 类对象的字段(即静态字段)按照如下顺序进行初始化:
1 2 3 1、默认初始化 2、定义初始化 3、静态初始化语句初始化 
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package  chapter5;public  class  InitialOrder2  {  public  static  void  main (String[] args)  throws  ClassNotFoundException {          ExperimentObject  object  =  null ;          Class.forName("chapter5.ExperimentObject" );   } } class  ExperimentObject  {     static  int  i  =  f(10 );   static  {     System.out.println("定义初始化后 i:"  + i);          i = 20 ;     System.out.println("静态初始化语句初始化后 i:"  + i);   }   public  static  int  f (int  a)  {     System.out.println("默认初始化后 i:"  + i);     return  10 ;   } } 
类对象初始化中“默认初始化”初始化阶段触发条件:第一次遇见类的声明,从而引发加载类的Class文件和创建类对象。Class.forName(相应类类路径)语句第一次执行。
1.2、其他 关于实例对象和类对象初始化有以下几点说明:
实例对象和类对象初始化中“默认初始化”初始化阶段的默认初始化值遵照Java编程思想#一切都是对象 中的表2 
类对象初始化先于实例对象初始化 
类对象初始化至多进行1次,实例对象初始化可进行任意多次 
 
最后是一个关于实例对象和类对象初始化的综合示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 public  class  Main  {  static  int  a;   static  int  b  =  f();   static  int  c  =  20 ;   static  int  f ()  {     return  c + 10 ;   }   static  {     System.out.println("static initialize start" );     System.out.println(a);     System.out.println(c);     a = 10 ;     c = 30 ;     System.out.println(a);     System.out.println(c);     System.out.println("static initialize end" );   }   int  d;   int  f  =  h();   int  g  =  20 ;   int  h ()  {     return  g + 10 ;   }   {     System.out.println("initialize start" );     System.out.println(d);     System.out.println(g);     d = 10 ;     g = 40 ;     System.out.println(d);     System.out.println(g);     System.out.println("initialize end" );   }   public  Main ()  {     d = 20 ;     g = 30 ;     System.out.println("constructor print start" );     System.out.println(d);     System.out.println(g);     System.out.println("constructor print end" );   }      public  static  void  main (String[] args)  throws  ClassNotFoundException {     System.out.println(Main.a);     System.out.println(Main.b);     System.out.println(Main.c);     System.out.println("分割线-------------" );          Main  main  =  new  Main ();     System.out.println(main.d);     System.out.println(main.f);     System.out.println(main.g);   } } 
二、清理 实例对象和类对象由垃圾回收器负责进行回收。
三、其他 3.1、方法重载 1、重载方法之间以参数类型列表进行区分,不能以返回值进行区分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package  chapter5;public  class  Overloading  {  public  static  void  main (String[] args)  {     Overloading  o  =  new  Overloading ();     byte  a  =  10 ;     o.f(a);     o.g(o);     o.h(a);     o.j(o);   }   public  void  f (short  a)  {     System.out.println("f(short)" );   }   public  void  g (Object a)  {     System.out.println("g(Object)" );   }   public  void  h (short  a)  {     System.out.println("h(short)" );   }   public  void  h (byte  a)  {     System.out.println("h(byte)" );   }   public  void  j (Object a)  {     System.out.println("j(Object)" );   }   public  void  j (Overloading a)  {     System.out.println("j(Overloading)" );   } } 
3.2、构造器 当且只当不显式指定构造器时,编译器才会自动创建一个默认构造器。
3.3、this关键词 this关键词有两个用途:“指代本实例对象”和“在构造器中调用构造器”。示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package  chapter5;public  class  ThisKeyword  {  int  a;   int  b;   public  ThisKeyword (int  a, int  b)  {     this .a = a;     this .b = b;   }   public  ThisKeyword (int  a)  {     this (a, 10 );   }   public  void  setA (int  A)  {     this .a = A;   }   public  ThisKeyword getThisInstance ()  {     return  this ;   } } 
使用this调用构造器有以下限制:
“this调用构造器”只能在构造器中使用 
“this调用构造器”只能置于构造器最起始处 
“this调用构造器”在同一个构造器中至多使用1次 
 
3.4、finalize()方法 垃圾回收过程中,在回收对象之前至多会调用1次对象的finalize()方法,因此,该方法机制的设计初衷是我们可以覆盖实现自己的finalize()方法,在覆盖实现后的finalize()方法中做垃圾回收前的清理工作,但是基于以下两点原因,我们不应该使用finalize()方法机制来做垃圾回收前的清理工作:
有可能不进入垃圾回收过程,比如通过System.exit()命令直接退出Java进程 
在垃圾回收过程中,回收对象之前至多会调用1次对象的finalize()方法,但也有可能不调用 
 
3.5、内存泄漏 在Java中,也有可能出现内存泄漏的情形,比如在本地方法中分配的内存(例如C/C++语言实现的本地方法中使用malloc方法分配内存)。
3.6、数组初始化 数组初始化有3种形式,需要注意的是,第1种只能用在数组定义处。分别以“int[]”和“String[]”数组为例进行说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package  chapter5;public  class  ArrayInitialize  {  public  static  void  main (String[] args)  {          int [] a = {1 , 2 , 3 };         int [] aa = new  int []{1 , 2 , 3 };     int [] aaa = new  int [3 ];     aaa[0 ] = 1 ;     aaa[1 ] = 2 ;     aaa[2 ] = 3 ;          String[] b = {"hello" , "world" };         String[] bb = new  String []{"hello" , "world" };     String[] bbb = new  String [2 ];     bbb[0 ] = "hello" ;     bbb[1 ] = "world" ;   } } 
备注: Java编程思想#一切都是对象 中的表2
3.7、可变参数列表 自从JDK 1.5开始,Java引入了对可变参数列表的支持,可变参数列表本质上还是一个数组,因此适用于“foreach语法”,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package  chapter5;public  class  VarArg  {  public  void  f (int ... a)  {     for  (int  aa : a) {       System.out.println(aa);     }   }   public  void  g (Object... b)  {     for  (Object bb : b) {       System.out.println(bb);     }   } } 
3.8、方法实现体中的变量不会进行默认初始化 方法实现体中的变量不会像类中的字段(包括普通和静态字段)一样进行默认初始化。编译过程会因为存在未被初始化的变量而失败。示例代码如下:
1 2 3 4 5 6 7 8 9 10 package  chapter5;public  class  MethodVariableInitialization  {  void  f ()  {     int  b;          System.out.println(b);   } } 
3.9、失效的“向前引用” ###根据Java编程思想#一切都是对象 可知,Java解决了“向前引用”的问题,即在某处可使用在其后定义的资源。
1 2 3 4 5 6 7 8 9 10 11 public  class  Main  {  int  a  =  f(c);      int  c  =  10 ;   int  f (int  n)  {     return  n;   }    } 
在int a = f(c);语句处,编译器报出Illegal forward reference(非法的向前引用)错误。这看起来是“向前引用”失效了。f()方法,如果上面这段代码编译通过的话,f()方法最后得到的传入值将是“0”(c的默认初始化值为0)。为了防止这种“surprise”的产生,编译器报出了如上错误。(如果将int a = f(c);语句和int c = 10;语句互换位置,编译器就不会报错)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public  class  Main  {  int  a  =  g();   int  g ()  {     return  c;   }   public  static  void  main (String[] args)  {     Main  main  =  new  Main ();     System.out.println(main.a);   }   int  c  =  10 ; } 
该段代码编译能够通过,但是从严格意义上来,如果按照上述思路,那么int a = g();语句也是一个非法的向前引用。