转:Java实例化类的方法

面试遇到的问题:类实例化的方法有几种?遗憾我回答了三种,如果你只知道new的话,那差太远了,还是看看这里吧

Java中,类的实例化方法有四种途径:

1)使用new操作符
2)调用Class对象的newInstance()方法
3)调用clone()方法,对现有实例的拷贝

4)通过ObjectInputStream的readObject()方法反序列化类

1.ClassInstance.java
import java.io.*;  
  
class ClassInstance implements Cloneable, Serializable {  
     private String str = "测试...";  
     public void fun(){  
         System.out.println(str);  
     }  
     public ClassInstance(String str){  
         System.out.println("有参类的实例化");  
         this.str += str;  
     }  
     public ClassInstance(){  
         System.out.println("无参类的实例化");  
     }  
     public Object clone(){  
         return this;  
     }  
}

2.ClassInstanceTest.java
import java.io.*;  
import java.lang.reflect.*;  
  
public class ClassInstanceTest{  
     public static void main(String[] args) throws ClassNotFoundException, InstantiationException,  
            IllegalAccessException, IOException,InvocationTargetException, NoSuchMethodException{  
         //第一种类的实例化方式
         ClassInstance ci01 = new ClassInstance("01");  
         ci01.fun();  
  
         //第二种类的实例化方式
         ClassInstance ci02 = (ClassInstance) Class.forName("ClassInstance").newInstance();  
         ci02.fun();  
  
         //第三种类的实例化方式
         ClassInstance ci03 = (ClassInstance) ci01.clone();  
         ci03.fun();  
  
         //第四种类的实例化方式
         FileOutputStream fos = new FileOutputStream("ci.tmp");  
         ObjectOutputStream oos = new ObjectOutputStream(fos);  
         oos.writeObject(ci01);  
         oos.close();  
         fos.close();  
          
         FileInputStream fis = new FileInputStream("ci.tmp");  
         ObjectInputStream ois = new ObjectInputStream(fis);  
          
         ClassInstance ci04  = (ClassInstance) ois.readObject();  
         ois.close();  
         fis.close();  
          
         ci04.fun();  
         System.out.println("--------------------额外测试--------------------");  
         ClassInstance ci05 = null;  
         //额外的思考 在第二种类实例化的方式中有没有一种方法实现有参数的构造方式
         //获得类的构造信息
         Constructor[] ctor = Class.forName("ClassInstance").getDeclaredConstructors();  
         //找到我们需要的构造方法
         for(int i=0;i<ctor.length;i++ ){  
             Class[] cl = ctor.getParameterTypes();  
             if(cl.length == 1){  
                 //实例化对象
                 ci05 = (ClassInstance) Class.forName("ClassInstance").getConstructor(cl).newInstance(new Object[]{"05"});  
             }  
         }  
         ci05.fun();  
     }  
}

3.输出结果
  1. 有参类的实例化  
  2. 测试...01  
  3. 无参类的实例化  
  4. 测试...  
  5. 测试...01  
  6. 测试...01  
  7. -------------------额外测试--------------------  
  8. 有参类的实例化  
  9. 测试...05

除了这几种情况可以实例化一个Java类对象外,隐式调用实例化也是利用了已上集中情况。例如常见的方法:
public class ClassInstance{  
public ClassInstance(){  
}  
public ClassInstance getInstance(){  
    return new ClassInstance();  
}  
}
/*隐式调用实例化乍起来一看像 单例模式 ,但与 单列模式 比起来还有本质的不同。敬请读者参考《研磨设计模式》里对 单例模式 的精彩讲解。*/


通过观察结果,我们发现无论哪一种方式必须经过的一步---调用构造方法。无论怎样构造函数作为初始化类的意义怎样都不会改变。


你可能感兴趣的:(类实例化方法)