当前位置: 移动技术网 > IT编程>开发语言>Java > Java中创建对象的5种方式总结

Java中创建对象的5种方式总结

2019年07月22日  | 移动技术网IT编程  | 我要评论

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

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

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

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

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

如果你运行了末尾的的程序,你会发现方法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<employee> 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方法的区别,

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对象。

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<employee> 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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网