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

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

2017年10月26日13:43:11来源:海文国际         378
分享到:
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