java中创建对象的5种方式-mile米乐体育
本文由码农网 – 孙腾浩原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!
作为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方法调用有参数的和私有的构造函数。
constructorconstructor = 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 constructorconstructor = 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
翻译作者:码农网 – 孙腾浩
[ 转载必须在正文中标注并保留原文链接、译文链接和译者等信息。]