前言
HI好港,歡迎來(lái)到《每周一博》愉镰。今天是十一月第二周,我給大家簡(jiǎn)單分享一下Java創(chuàng)建一個(gè)對(duì)象的幾種方式钧汹。
- 使用new關(guān)鍵字:
Student student = new Student();
這是最常見(jiàn)的創(chuàng)建對(duì)象的方式丈探,通過(guò)這種方式還可以調(diào)用任意的構(gòu)造函數(shù)(無(wú)參的和有參的)。
使用new關(guān)鍵字創(chuàng)建對(duì)象拔莱,實(shí)際上是做了兩個(gè)工作碗降,一是在內(nèi)存中開(kāi)辟空間,二是初始化對(duì)象塘秦。但是new 關(guān)鍵字只能創(chuàng)建非抽象對(duì)象讼渊。
- 通過(guò)反射創(chuàng)建對(duì)象:
對(duì)于任意一個(gè)正在運(yùn)行的類,通過(guò)反射都能動(dòng)態(tài)獲取到它的屬性和方法尊剔。反射創(chuàng)建對(duì)象分為兩種方式:
A. 使用Class類的newInstance()方法爪幻,
B. 使用Constructor類的newInstatnce()方法。
Student student2 = (Student)Class.forName("根路徑.Student").newInstance();
Student stu = Student.class.newInstance();
Constructor<Student> constructor =Student.class.getInstance();
Student stu = constructor.newInstance();
兩者區(qū)別在于:
Class.newInstance() 只能夠調(diào)用無(wú)參的構(gòu)造函數(shù)须误,即默認(rèn)的構(gòu)造函數(shù)挨稿;
Constructor.newInstance() 可以根據(jù)傳入的參數(shù),調(diào)用任意構(gòu)造構(gòu)造函數(shù)京痢。
事實(shí)上Class的newInstance方法內(nèi)部調(diào)用Constructor的newInstance方法奶甘,這也是眾多框架Spring、Hibernate祭椰、Struts等使用后者的原因甩十。
- 使用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接口并實(shí)現(xiàn)其定義的clone方法橄霉,這也是原型模式的應(yīng)用窃爷。
Student stu2 = <Student>stu.clone();
克隆模式有深拷貝和淺拷貝之分,淺拷貝下引用類型是共用的姓蜂,一改全改按厘,所以需要對(duì)引用行的字段也進(jìn)行拷貝,比如我們對(duì)Student里面課程的集合進(jìn)行深拷貝钱慢。
@override
public Student clone() {
try {
Student stu = (Student) super.clone();
stu.classes = (ArrayList<String>) this.classes.clone();
return stu;
} catch (CloneNotSupportedException e) {
return null;
}
}
克隆的優(yōu)點(diǎn)是直接在內(nèi)存中拷貝二進(jìn)制流逮京,比new一個(gè)對(duì)象性能要好很多,特別是再循環(huán)體內(nèi)產(chǎn)生大量的對(duì)象時(shí)束莫,缺點(diǎn)是構(gòu)造函數(shù)不會(huì)執(zhí)行懒棉,所以需要自己權(quán)衡考慮。
- 使用反序列化:
當(dāng)我們序列化和反序列化一個(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接口,然后在使用ObjectInputStream的readObject方法來(lái)創(chuàng)建對(duì)象怀各。
// 序列化
ObjectInputStream in = new ObjectInputStream (new FileInputStream("data.obj"));
// 反序列化
Student stu3 = (Student)in.readObject();
結(jié)尾:
本周給大家簡(jiǎn)單介紹了Java創(chuàng)建對(duì)象的四種方式倔韭。感謝大家的閱讀,我們下周再見(jiàn)瓢对。