首頁 > IT知識 > 爱赢国际注册教程之Java中創建對象的5種方式

爱赢国际注册教程之Java中創建對象的5種方式

2017年10月26日13:43:11來源:海文國際         831
分享到:
IT知識文章: 

作為Java開發者,我們每天創建很多對象,但我們通常使用依賴管理系統,比如Spring去創建對象。然而這里有很多創建對象的方法,我們會在這篇文章中學到。

Java中有5種創建對象的方式,下面給出它們的例子還有它們的字節碼

爱赢国际注册教程之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