java中创建对象的5种方式-亚博电竞手机版

本文由码农网 – 孙腾浩原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

作为java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如spring去创建对象。然而这里有很多创建对象的方法,我们会在这篇文章中学到。

java中有5种创建对象的方式,下面给出它们的例子还有它们的字节码

使用new关键字 } → 调用了构造函数
使用class类的newinstance方法 } → 调用了构造函数
使用constructor类的newinstance方法 } → 调用了构造函数
使用clone方法 } → 没有调用构造函数
使用反序列化 } → 没有调用构造函数

如果你运行了末尾的的程序,你会发现方法1,2,3用构造函数创建对象,方法4,5没有调用构造函数。

1.使用new关键字

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

employee emp1 = new employee();
0: new           #19          // class org/programming/mitra/exercises/employee 3: dup 4: invokespecial #21          // method org/programming/mitra/exercises/employee."":()v

2.使用class类的newinstance方法

我们也可以使用class类的newinstance方法创建对象。这个newinstance方法调用无参的构造函数创建对象。

我们可以通过下面方式调用newinstance方法创建对象:

employee emp2 = (employee) class.forname("org.programming.mitra.exercises.employee").newinstance();

或者

employee emp2 = employee.class.newinstance();
51: invokevirtual    #70    // method java/lang/class.newinstance:()ljava/lang/object;

3.使用constructor类的newinstance方法

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

constructor constructor = employee.class.getconstructor(); employee emp3 = constructor.newinstance();
111: invokevirtual  #80  // method java/lang/reflect/constructor.newinstance:([ljava/lang/object;)ljava/lang/object;

这两种newinstance方法就是大家所说的反射。事实上class的newinstance方法内部调用constructor的newinstance方法。这也是众多框架,如spring、hibernate、struts等使用后者的原因。想了解这两个newinstance方法的区别,请看这篇creating objects through reflection in java with example.

4.使用clone方法

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

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

employee emp4 = (employee) emp3.clone();
162: invokevirtual #87  // method org/programming/mitra/exercises/employee.clone ()ljava/lang/object;

5.使用反序列化

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

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

objectinputstream in = new objectinputstream(new fileinputstream("data.obj")); employee emp5 = (employee) in.readobject();
261: invokevirtual  #118   // method java/io/objectinputstream.readobject:()ljava/lang/object;

我们从上面的字节码片段可以看到,除了第1个方法,其他4个方法全都转变为invokevirtual(创建对象的直接方法),第一个方法转变为两个调用,new和invokespecial(构造函数调用)。

例子

让我们看一看为下面这个employee类创建对象:

class employee implements cloneable, serializable {     private static final long serialversionuid = 1l;     private string name;     public employee() {         system.out.println("employee constructor called...");     }     public string getname() {         return name;     }     public void setname(string name) {         this.name = name;     }     @override     public int hashcode() {         final int prime = 31;         int result = 1;         result = prime * result   ((name == null) ? 0 : name.hashcode());         return result;     }     @override     public boolean equals(object obj) {         if (this == obj)             return true;         if (obj == null)             return false;         if (getclass() != obj.getclass())             return false;         employee other = (employee) obj;         if (name == null) {             if (other.name != null)                 return false;         } else if (!name.equals(other.name))             return false;         return true;     }     @override     public string tostring() {         return "employee [name="   name   "]";     }     @override     public object clone() {         object obj = null;         try {             obj = super.clone();         } catch (clonenotsupportedexception e) {             e.printstacktrace();         }         return obj;     } }

下面的java程序中,我们将用5种方式创建employee对象。你可以从github找到这些代码。

public class objectcreation {     public static void main(string... args) throws exception {         // by using new keyword         employee emp1 = new employee();         emp1.setname("naresh");         system.out.println(emp1   ", hashcode : "   emp1.hashcode());         // by using class class's newinstance() method         employee emp2 = (employee) class.forname("org.programming.mitra.exercises.employee")                                .newinstance();         // or we can simply do this         // employee emp2 = employee.class.newinstance();         emp2.setname("rishi");         system.out.println(emp2   ", hashcode : "   emp2.hashcode());         // by using constructor class's newinstance() method         constructor constructor = employee.class.getconstructor();         employee emp3 = constructor.newinstance();         emp3.setname("yogesh");         system.out.println(emp3   ", hashcode : "   emp3.hashcode());         // by using clone() method         employee emp4 = (employee) emp3.clone();         emp4.setname("atul");         system.out.println(emp4   ", hashcode : "   emp4.hashcode());         // by using deserialization         // serialization         objectoutputstream out = new objectoutputstream(new fileoutputstream("data.obj"));         out.writeobject(emp4);         out.close();         //deserialization         objectinputstream in = new objectinputstream(new fileinputstream("data.obj"));         employee emp5 = (employee) in.readobject();         in.close();         emp5.setname("akash");         system.out.println(emp5   ", hashcode : "   emp5.hashcode());     } }

程序会输出:

employee constructor called... employee [name=naresh], hashcode : -1968815046 employee constructor called... employee [name=rishi], hashcode : 78970652 employee constructor called... employee [name=yogesh], hashcode : -1641292792 employee [name=atul], hashcode : 2051657 employee [name=akash], hashcode : 63313419

译文链接:http://www.codeceo.com/article/5-ways-java-create-object.html
英文原文:5 different ways to create objects in java
翻译作者:码农网 – 孙腾浩
转载必须在正文中标注并保留原文链接、译文链接和译者等信息。]

展开全文
内容来源于互联网和用户投稿,文章中一旦含有亚博电竞手机版的联系方式务必识别真假,本站仅做信息展示不承担任何相关责任,如有侵权或涉及法律问题请联系亚博电竞手机版删除

最新文章

网站地图