1. 四種方式
new
反射
Clone
反序列化
1.1 new
最常見(jiàn)的創(chuàng)建對(duì)象的方式,通過(guò)這種方式我們還可以調(diào)用任意的構(gòu)造器(無(wú)參的和有參的)
public class Main {
public static void main(String[] args) {
Person person1 = new Person();
Person person2 = new Person("fsx", 18);
}
}
1.2 反射
Class.newInstance
這是我們運(yùn)用反射創(chuàng)建對(duì)象時(shí)最常用的方法。Class類的newInstance使用的是類的public的無(wú)參構(gòu)造器。因此也就是說(shuō)使用此方法創(chuàng)建對(duì)象的前提是必須有public的無(wú)參構(gòu)造器才行,否則報(bào)錯(cuò)。
public class Main {
public static void main(String[] args) throws Exception {
Person person = Person.class.newInstance();
System.out.println(person); // Person{name='null', age=null}
}
}
Constructor.newInstance
本方法和Class類的newInstance方法很像,但是比它強(qiáng)大很多。 java.lang.relect.Constructor類里也有一個(gè)newInstance方法可以創(chuàng)建對(duì)象。我們可以通過(guò)這個(gè)newInstance方法調(diào)用有參數(shù)(不再必須是無(wú)參)的和私有的構(gòu)造函數(shù)(不再必須是public)。
public class Main {
public static void main(String[] args) throws Exception {
// 包括public的和非public的,當(dāng)然也包括private的
Constructor<?>[] declaredConstructors = Person.class.getDeclaredConstructors();
// 只返回public的~~~~~~(返回結(jié)果是上面的子集)
Constructor<?>[] constructors = Person.class.getConstructors();
Constructor<?> noArgsConstructor = declaredConstructors[0];
Constructor<?> haveArgsConstructor = declaredConstructors[1];
noArgsConstructor.setAccessible(true); // 非public的構(gòu)造必須設(shè)置true才能用于創(chuàng)建實(shí)例
Object person1 = noArgsConstructor.newInstance();
Object person2 = declaredConstructors[1].newInstance("fsx", 18);
System.out.println(person1);
System.out.println(person2);
}
}
1.3 clone
調(diào)用一個(gè)對(duì)象的clone方法,JVM就會(huì)創(chuàng)建一個(gè)新的對(duì)象,將前面的對(duì)象的內(nèi)容全部拷貝進(jìn)去,用clone方法創(chuàng)建對(duì)象并不會(huì)調(diào)用任何構(gòu)造函數(shù)。 要使用clone方法,我們必須先實(shí)現(xiàn)Cloneable接口并復(fù)寫(xiě)Object的clone方法。
public class Person implements Cloneable {
...
// 訪問(wèn)權(quán)限寫(xiě)為public,并且返回值寫(xiě)為person
@Override
public Person clone() throws CloneNotSupportedException {
return (Person) super.clone();
}
...
}
public class Main {
public static void main(String[] args) throws Exception {
Person person = new Person("fsx", 18);
Object clone = person.clone();
System.out.println(person);
System.out.println(clone);
System.out.println(person == clone); //false
}
}
這種復(fù)制稱為淺復(fù)制,如果需要clone完成深復(fù)制則需要在Son也實(shí)現(xiàn)Cloneable接口和重寫(xiě)clone方法。
1.4 反序列化
列化和反序列化一個(gè)對(duì)象,JVM會(huì)給我們創(chuàng)建一個(gè)單獨(dú)的對(duì)象,在反序列化時(shí),JVM創(chuàng)建對(duì)象并不會(huì)調(diào)用任何構(gòu)造函數(shù)。為了反序列化一個(gè)對(duì)象,我們需要讓我們的類實(shí)現(xiàn)Serializable接口。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-493129.html
public class Main {
public static void main(String[] args) throws Exception {
Person person = new Person("fsx", 18);
byte[] bytes = SerializationUtils.serialize(person);
// 字節(jié)數(shù)組:可以來(lái)自網(wǎng)絡(luò)、可以來(lái)自文件(本處直接本地模擬)
Object deserPerson = SerializationUtils.deserialize(bytes);
System.out.println(person);
System.out.println(deserPerson);
System.out.println(person == deserPerson);
}
}
2 對(duì)比
Java創(chuàng)建實(shí)例對(duì)象,并不一定必須要調(diào)用構(gòu)造器的。
創(chuàng)建對(duì)象方式 是否調(diào)用了構(gòu)造器
new關(guān)鍵字 是
Class.newInstance 是
Constructor.newInstance 是
Clone 否
反序列化 否文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-493129.html
到了這里,關(guān)于Java創(chuàng)建對(duì)象的4種方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!