Java类的实例化探究


java类的实例化(instantiation)具有显性的和隐性的区别。

一般编程时,我们锁使用new的方法实例化,这是最简单直接的显性实例化。另外还有三种实例化,分别为反射机制中的newInstance()方法,类的clone()方法 和 解串行化使用的ObjecInputStream中的getObject()方法。

而隐性的实例化则出现在java程序的整个生命周期中,包括String 、 Class ,StringBuffer 或者StringBuilder的实例化。

详细内容如下:


显性的实例化:

1.直接使用new关键字创建新的对象

调用相应的构造函数完成实例化。(类中的非静态成员变量如果有初始化语句,都会被隐式的加入到构造函数中)代码如下:

  1. public class Test  {  
  2.   
  3.     String strA = "xyz";  
  4.     String strB ;  
  5.       
  6.     public Test(String str){  
  7.         strB = str ;  
  8.     }  
  9.     public static void main(String[] args){  
  10.             Test t = new Test("abc");  
  11.     }  
  12.       
  13. }  
在eclipse中装了ASM bytecode插件后,观察.class文件中的构造函数对应的字节码如下:
  1. INVOKESPECIAL Object.<init>() : void  
  2.    ALOAD 0: this  
  3.    LDC "xyz"  
  4.    PUTFIELD Test.strA : String  
  5.    ALOAD 0: this  
  6.    ALOAD 1: str  
  7.    PUTFIELD Test.strB : String  
  8.    RETURN  

关键在于LDC"xyz"这条指令,明显可以看出,这是用于strA初始化的字符串。

由此我们可以归纳出,在没有调用 本类中其他的构造函数的情况下,每次类的构造函数中都会按如下顺序进行:

a)隐式(或显性)的调用父类的构造函数,

b)然后执行写在构造函数外的成员变量的初始化赋值

c)最后再执行构造函数中的命令。

如果是有显性的调用本类其他构造函数(必须是放在构造函数第一步执行),那么对于这个构造函数,处理过程就简单些了:

a)调用那个构造函数。

b)执行之后的代码。

  1. public class Test  {  
  2.   
  3.     String strA = "xyz";  
  4.     String strB ;  
  5.       
  6.     public Test(String str){  
  7.         this();  
  8.     }  
  9.     public Test(){  
  10.         strB = "mno";  
  11.     }  
  12.       
  13.     public void print(){  
  14.         System.out.println(strB);  
  15.     }  
  16.       
  17.     public static void main(String[] args){  
  18.             Test t = new Test("abc");  
  19.             t.print();  
  20.     }  
  21.       
  22.       
  23. }  
执行结果为
  1. mno  

至于为什么一定要将另外一个构造函数放在构造函数的第一步:必须先处理好heap中的变量初始化后才能下一步执行。

  • 1
  • 2
  • 下一页

相关内容