【学习笔记】Java中生成对象的5中方法

概述:本文介绍以下java五种创建对象的方式:

1.用new语句创建对象,这是最常用的创建对象的方式。

2.使用Class类的newInstance方法

3.运用反射手段,调用java.lang.reflect.Constructor类的newInstance()实例方法。

4.调用对象的clone()方法。

5.运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法.

一、使用new关键字

  这是最常见也是最简单的创建对象的方式了。通过这种方式,我们可以调用任意的构造函数(无参的和带参数的)。

二、使用Class类的newInstance方法

  使用Class类的newInstance方法创建对象。这个newInstance方法调用无参的构造函数创建对象

三、使用Constructor类的newInstance方法

  和Class类的newInstance方法很像, java.lang.reflect.Constructor类里也有一个newInstance方法可以创建对象。我们可以通过这个newInstance方法调用有参数的和私有的构造函数。

  newInstance方法内部调用Constructor的newInstance方法。这也是众多框架,如Spring、Hibernate、Struts等使用后者的原因。

四、使用clone方法

   无论何时我们调用一个对象的clone方法,jvm就会创建一个新的对象,将前面对象的内容全部拷贝进去。用clone方法创建对象并不会调用任何构造函数。

要使用clone方法,我们需要先实现Cloneable接口并实现其定义的clone方法。

 1 public class Customer implements Cloneable{  
 2 private String name;  
 3 private int age;  
 4 public Customer(){  
 5   this("unknown",0);  
 6   System.out.println("call default constructor");  
 7 }  
 8 public Customer(String name,int age){  
 9   this.name=name;  
10   this.age=age;  
11   System.out.println("call second constructor");  
12 }  
13 public Object clone()throws CloneNotSupportedException{  
14 return super.clone();  
15 }  
16 public boolean equals(Object o){  
17   if(this==o)return true;  
18   if(! (o instanceof Customer)) return false;  
19   final Customer other=(Customer)o;  
20   if(this.name.equals(other.name) && this.age==other.age)  
21      return true;  
22   else  
23      return false;  
24 }  
25 public String toString(){  
26 return "name="+name+",age="+age;  
27 }  
28 public static void main(String args[])throws Exception{  
29 //运用反射手段创建Customer对象  
30 Class objClass=Class.forName("Customer");  
31 Customer c1=(Customer)objClass.newInstance(); //会调用Customer类的默认构造方法  
32 System.out.println("c1: "+c1); //打印name=unknown,age=0  
33    
34 //用new语句创建Customer对象  
35 Customer c2=new Customer("Tom",20);  
36 System.out.println("c2: "+c2); //打印name=tom,age=20  
37    
38 //运用克隆手段创建Customer对象  
39 Customer c3=(Customer)c2.clone(); //不会调用Customer类的构造方法  
40 System.out.println("c2==c3 : "+(c2==c3)); //打印false  
41 System.out.println("c2.equals(c3) : "+c2.equals(c3)); //打印true  
42 System.out.println("c3: "+c3); //打印name=tom,age=20  
43 }  
44 }  

五、使用反序列化

  当我们序列化和反序列化一个对象,jvm会给我们创建一个单独的对象。在反序列化时,jvm创建对象并不会调用任何构造函数。

为了反序列化一个对象,我们需要让我们的类实现Serializable接口。

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp = (Employee) in.readObject();

注意:除了第1个方法,其他4个方法全都转变为invokevirtual(创建对象的直接方法),第一个方法转变为两个调用,new和invokespecial(构造函数调用)。

 

除了以上5种显式地创建对象的方式以外,在程序中还可以隐含地创建对象,包括以下几种情况:

1.对于java命令中的每个命令行参数,Java虚拟机都会创建相应的String对象,并把它们组织到一个String数组中,再把该数组作为参数传给程序入口main(String args[])方法。

2.程序代码中的String类型的直接数对应一个String对象,例如:

  1. String s1="Hello";  
  2. String s2="Hello"; //s2和s1引用同一个String对象  
  3. String s3=new String("Hello");  
  4. System.out.println(s1==s2); //打印true  
  5. System.out.println(s1==s3); //打印false  

执行完以上程序,内存中实际上只有两个String对象,一个是直接数,由Java虚拟机隐含地创建,还有一个通过new语句显式地创建。

3.字符串操作符“+”的运算结果为一个新的String对象。例如:

 
  1. String s1="H";  
  2. String s2=" ello";  
  3. String s3=s1+s2; //s3引用一个新的String对象  
  4. System.out.println(s3=="Hello"); //打印false  
  5. System.out.println(s3.equals("Hello")); //打印true  

4.当Java虚拟机加载一个类时,会隐含地创建描述这个类的Class实例.

参考资料:

java中生成对象的方式有多种,如下所示:

 1、使用new操作符,这是最普遍的一种
   如:String s=new String("abc");
 
 2、使用反射动态生成
    利用Class,ClassLoader,Constructor中的方法可以动态的生成类实例
    如:Object o=Class.forName("java.lang.String").newInstance();
        Object o=String.class.getClassLoader.loadClass("java.lang.String").newInstance();
        以上的方式需要目标类拥有公有无参构造函数
    以下使用Constructor进行动态生成
    class User{
       public User(String user,Integer id){}
    }
    Constructor c=User.class.getConstructor(new Class[]{String.class,Integer.class});
    User user=(User)c.newInstance(new Object[]{"zhang san",123});
 
3、使用克隆生成对象
   例如使用一个实现了Cloneable接口的对象,调用其clone()方法获得该对象的一份拷贝
   
4、利用反序列化从流中生成对象
   利用ObjectInptuStream的readObject()方法生成对象
posted @ 2017-05-28 16:01  滕秋宇  阅读(366)  评论(0编辑  收藏  举报