• 学科介绍

  • 课程大纲

  • 就业薪资

  • 师资力量

  • 课程视频

  • 学科介绍

  • 课程大纲

  • 就业薪资

  • 师资力量

  • 课程视频

  • 学科介绍

  • 课程大纲

  • 就业薪资

  • 师资力量

  • 课程视频

  • 学科介绍

  • 课程大纲

  • 就业薪资

  • 师资力量

  • 学科介绍

  • 课程大纲

  • 就业薪资

  • 师资力量

  • 课程视频

  • 学科介绍

  • 课程大纲

  • 就业薪资

  • 师资力量

  • 课程视频

  • 学科介绍

  • 课程大纲

  • 就业薪资

  • 师资力量

  • 课程视频

  • 首页 > IT知识 > java培训教程之Java中创建对象的5种方式

    java培训教程之Java中创建对象的5种方式

    2017年10月26日13:43:11来源:OAEC         829
    分享到:
    IT知识文章: 

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

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

    java培训教程之Java中创建对象的5种方式

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

    1.使用new关键字

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

    Employeeemp1=newEmployee();

    0:new#19//classorg/programming/mitra/exercises/Employee

    3:dup

    4:invokespecial#21//Methodorg/programming/mitra/exercises/Employee."":()V

    2.使用Class类的newInstance方法

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

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

    Employeeemp2=(Employee)Class.forName("org.programming.mitra.exercises.Employee").newInstance();

    或者

    Employeeemp2=Employee.class.newInstance();

    51:invokevirtual#70//Methodjava/lang/Class.newInstance:()Ljava/lang/Object;

    3.使用Constructor类的newInstance方法

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

    Constructor<Employee>constructor=Employee.class.getConstructor();

    Employeeemp3=constructor.newInstance();

    111:invokevirtual#80//Methodjava/lang/reflect/Constructor.newInstance:([Ljava/lang/Object;)Ljava/lang/Object;

    这两种newInstance方法就是大家所说的反射。事实上Class的newInstance方法内部调用Constructor的newInstance方法。这也是众多框架,如Spring、Hibernate、Struts等使用后者的原因。

    4.使用clone方法

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

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

    Employeeemp4=(Employee)emp3.clone();

    162:invokevirtual#87//Methodorg/programming/mitra/exercises/Employee.clone()Ljava/lang/Object;

    5.使用反序列化

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

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

    ObjectInputStreamin=newObjectInputStream(newFileInputStream("data.obj"));

    Employeeemp5=(Employee)in.readObject();

    261:invokevirtual#118//Methodjava/io/ObjectInputStream.readObject:()Ljava/lang/Object;

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

    例子

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

    classEmployeeimplementsCloneable,Serializable{

    privatestaticfinallongserialVersionUID=1L;

    privateStringname;

    publicEmployee(){

    System.out.println("EmployeeConstructorCalled...");

    }

    publicStringgetName(){

    returnname;

    }

    publicvoidsetName(Stringname){

    this.name=name;

    }

    @Override

    publicinthashCode(){

    finalintprime=31;

    intresult=1;

    result=prime*result+((name==null)?0:name.hashCode());

    returnresult;

    }

    @Override

    publicbooleanequals(Objectobj){

    if(this==obj)

    returntrue;

    if(obj==null)

    returnfalse;

    if(getClass()!=obj.getClass())

    returnfalse;

    Employeeother=(Employee)obj;

    if(name==null){

    if(other.name!=null)

    returnfalse;

    }elseif(!name.equals(other.name))

    returnfalse;

    returntrue;

    }

    @Override

    publicStringtoString(){

    return"Employee[name="+name+"]";

    }

    @Override

    publicObjectclone(){

    Objectobj=null;

    try{

    obj=super.clone();

    }catch(CloneNotSupportedExceptione){

    e.printStackTrace();

    }

    returnobj;

    }

    }

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

    /**

    */

    publicclassObjectCreation{

    publicstaticvoidmain(String...args)throwsException{

    //Byusingnewkeyword

    Employeeemp1=newEmployee();

    emp1.setName("Naresh");

    System.out.println(emp1+",hashcode:"+emp1.hashCode());

    //ByusingClassclass'snewInstance()method

    Employeeemp2=(Employee)Class.forName("org.programming.mitra.exercises.Employee")

    .newInstance();

    //Orwecansimplydothis

    //Employeeemp2=Employee.class.newInstance();

    emp2.setName("Rishi");

    System.out.println(emp2+",hashcode:"+emp2.hashCode());

    //ByusingConstructorclass'snewInstance()method

    Constructor<Employee>constructor=Employee.class.getConstructor();

    Employeeemp3=constructor.newInstance();

    emp3.setName("Yogesh");

    System.out.println(emp3+",hashcode:"+emp3.hashCode());

    //Byusingclone()method

    Employeeemp4=(Employee)emp3.clone();

    emp4.setName("Atul");

    System.out.println(emp4+",hashcode:"+emp4.hashCode());

    //ByusingDeserialization

    //Serialization

    ObjectOutputStreamout=newObjectOutputStream(newFileOutputStream("data.obj"));

    out.writeObject(emp4);

    out.close();

    //Deserialization

    ObjectInputStreamin=newObjectInputStream(newFileInputStream("data.obj"));

    Employeeemp5=(Employee)in.readObject();

    in.close();

    emp5.setName("Akash");

    System.out.println(emp5+",hashcode:"+emp5.hashCode());

    }

    }

    程序会输出:

    EmployeeConstructorCalled...

    Employee[name=Naresh],hashcode:-1968815046

    EmployeeConstructorCalled...

    Employee[name=Rishi],hashcode:78970652

    EmployeeConstructorCalled...

    Employee[name=Yogesh],hashcode:-1641292792

    Employee[name=Atul],hashcode:2051657

    Employee[name=Akash],hashcode:63313419