Java中創(chuàng )建對象的四種方法 收藏Java中創(chuàng )建對象的四種方式
1.用new語(yǔ)句創(chuàng )建對象,這是最常見(jiàn)的創(chuàng )建對象的方法。
2.運用反射手段,調用java.lang.Class或者java.lang.reflect.Constructor類(lèi)的newInstance()實(shí)例方法。
3.調用對象的clone()方法。
4.運用反序列化手段,調用java.io.ObjectInputStream對象的 readObject()方法。
第一種最常見(jiàn)
使用new關(guān)鍵字:這是我們最常見(jiàn)的也是最簡(jiǎn)單的創(chuàng )建對象的方式,通過(guò)這種方式我們還可以調用任意的夠贊函數(無(wú)參的和有參的)。比如:Student student = new Student();
使用Class類(lèi)的newInstance方法:我們也可以使用Class類(lèi)的newInstance方法創(chuàng )建對象,這個(gè)newInstance方法調用無(wú)參的構造器創(chuàng )建對象,如:Student student2 = (Student)Class.forName("根路徑.Student").newInstance(); 或者:Student stu = Student.class.newInstance();
使用Constructor類(lèi)的newInstance方法:本方法和Class類(lèi)的newInstance方法很像,java.lang.relect.Constructor類(lèi)里也有一個(gè)newInstance方法可以創(chuàng )建對象。我們可以通過(guò)這個(gè)newInstance方法調用有參數的和私有的構造函數。如: Constructor<Student> constructor = Student.class.getInstance(); Student stu = constructor.newInstance(); 這兩種newInstance的方法就是大家所說(shuō)的反射,事實(shí)上Class的newInstance方法內部調用Constructor的newInstance方法。這也是眾多框架Spring、Hibernate、Struts等使用后者的原因。
使用Clone的方法:無(wú)論何時(shí)我們調用一個(gè)對象的clone方法,JVM就會(huì )創(chuàng )建一個(gè)新的對象,將前面的對象的內容全部拷貝進(jìn)去,用clone方法創(chuàng )建對象并不會(huì )調用任何構造函數。要使用clone方法,我們必須先實(shí)現Cloneable接口并實(shí)現其定義的clone方法。如:Student stu2 = <Student>stu.clone();這也是原型模式的應用。
使用反序列化:當我們序列化和反序列化一個(gè)對象,JVM會(huì )給我們創(chuàng )建一個(gè)單獨的對象,在反序列化時(shí),JVM創(chuàng )建對象并不會(huì )調用任何構造函數。為了反序列化一個(gè)對象,我們需要讓我們的類(lèi)實(shí)現Serializable接口。如:ObjectInputStream in = new ObjectInputStream (new FileInputStream("data.obj")); Student stu3 = (Student)in.readObject();
我大一的時(shí)候學(xué)過(guò)一學(xué)期的C,時(shí)間有點(diǎn)久了只能記住一點(diǎn)點(diǎn)。印象最深刻的就是開(kāi)頭那個(gè)include。。.
說(shuō)回來(lái)Java和C其實(shí)代碼風(fēng)格是很相似的。什么面向過(guò)程什么面向對象,說(shuō)起來(lái)很繞,甚至我剛工作時(shí)還是很迷糊,但是工作一段時(shí)間就能明白了。
java中的對象可以理解為數據存儲對象,比如說(shuō)數據庫里有個(gè)person表,對應的實(shí)體類(lèi)一定要有一個(gè)person類(lèi),這個(gè)類(lèi)里一般會(huì )有一些簡(jiǎn)單屬性name,sex之類(lèi)的。這些是每一個(gè)person都會(huì )有的,書(shū)上往往都會(huì )說(shuō)“把大千世界看成一個(gè)個(gè)的對象”,這樣太繞你讀不懂就理解為數據庫person的每行都有name,sex字段。
至于方法,就是為person編寫(xiě)的業(yè)務(wù)程序。你的代碼需要person有一個(gè)聽(tīng)的功能,你就定義一個(gè) void say(),如果這個(gè)person什么都不用做,那就沒(méi)有方法。
在學(xué)習反射機制時(shí),總結一下獲得類(lèi)對象方式:
第一種方式:通過(guò)類(lèi)本身來(lái)獲得對象
Java代碼
Class classname =
this
.getClass();
第二種方式:通過(guò)子類(lèi)的實(shí)例獲取父類(lèi)對象
Java代碼
ClassName cn =
new
ClassName();
UserClass = cn.getClass();
Class SubUserClass = UserClass.getSuperclass();
第三種方式:通過(guò)類(lèi)名加.class獲取對象
Java代碼
Class ForClass = **.**.ClassName.
class
;(類(lèi)在包中的路徑加.
class
)
第四種方式:通過(guò)類(lèi)名的字符串獲取對象
Java代碼
Class ForName = Class.forName(
"**.**.ClassName"
);
類(lèi)是對一類(lèi)事物的描述。如“人”就是一個(gè)類(lèi),一個(gè)類(lèi)又有很多屬性和方法,如“人”有“名字”,“性別”“年齡”等屬性,有“行走”,“說(shuō)話(huà)”等方法。說(shuō)簡(jiǎn)單點(diǎn)就是屬性描述一個(gè)類(lèi)是什么樣的,而方法描述一個(gè)類(lèi)能干什么。我們說(shuō)創(chuàng )建一個(gè)類(lèi),就是寫(xiě)一個(gè)Java類(lèi),如
class Person{//類(lèi)
String name;。.//屬性
public void run(){..}//方法
}
而對象是類(lèi)的一個(gè)實(shí)例,如“張三”就是“人”這個(gè)類(lèi)的一個(gè)對象。我們可以通過(guò)如下語(yǔ)句來(lái)創(chuàng )建“張三”這個(gè)對象:Person zhangsan = new Person();這里用到了Person這個(gè)類(lèi)的一個(gè)默認構造函數來(lái)創(chuàng )建zhangsan這個(gè)對象。至于setXXX,getXXX分別用來(lái)設置和獲取屬性XXX的值。
Object是所有類(lèi)的父類(lèi),任何類(lèi)都默認繼承Object。Object類(lèi)到底實(shí)現了哪些方法?
1.clone方法
保護方法,實(shí)現對象的淺復制,只有實(shí)現了Cloneable接口才可以調用該方法,否則拋出異常。
2.getClass方法
final方法,獲得運行時(shí)類(lèi)型。
3.toString方法
該方法用得比較多,一般子類(lèi)都有覆蓋。
4.finalize方法
該方法用于釋放資源。因為無(wú)法確定該方法什么時(shí)候被調用,很少使用。
5.equals方法
該方法是非常重要的一個(gè)方法。一般equals和==是不一樣的,但是在Object中兩者是一樣的。子類(lèi)一般都要重寫(xiě)這個(gè)方法。
6.hashCode方法
該方法用于哈希查找,重寫(xiě)了equals方法一般都要重寫(xiě)hashCode方法。這個(gè)方法在一些具有哈希功能的Collection中用到。
一般必須滿(mǎn)足obj1.equals(obj2)==true。可以推出obj1.hash-
Code()==obj2.hashCode(),但是hashCode相等不一定就滿(mǎn)足equals。不過(guò)為了提高效率,應該盡量使上面兩個(gè)條件接近等價(jià)。
7.wait方法
wait方法就是使當前線(xiàn)程等待該對象的鎖,當前線(xiàn)程必須是該對象的擁有者,也就是具有該對象的鎖。wait()方法一直等待,直到獲得鎖或者被中斷。wait(long
timeout)設定一個(gè)超時(shí)間隔,如果在規定時(shí)間內沒(méi)有獲得鎖就返回。
調用該方法后當前線(xiàn)程進(jìn)入睡眠狀態(tài),直到以下事件發(fā)生。
(1)其他線(xiàn)程調用了該對象的notify方法。
(2)其他線(xiàn)程調用了該對象的notifyAll方法。
(3)其他線(xiàn)程調用了interrupt中斷該線(xiàn)程。
(4)時(shí)間間隔到了。
此時(shí)該線(xiàn)程就可以被調度了,如果是被中斷的話(huà)就拋出一個(gè)InterruptedException異常。
8.notify方法
該方法喚醒在該對象上等待的某個(gè)線(xiàn)程。
9.notifyAll方法
該方法喚醒在該對象上等待的所有線(xiàn)程。
Java中創(chuàng )建對象的四種方式 1.用new語(yǔ)句創(chuàng )建對象,這是最常見(jiàn)的創(chuàng )建對象的方法。
2.運用反射手段,調用java.lang.Class或者java.lang.reflect.Constructor類(lèi)的newInstance()實(shí)例方法。 3.調用對象的clone()方法。
4.運用反序列化手段,調用java.io.ObjectInputStream對象的 readObject()方法。下面演示了用前面3種方式創(chuàng )建對象的過(guò)程:public class Customer implements Cloneable{ private String name; private int age; public Customer(){ this("unknown",0); System.out.println("call default constructor"); } public Customer(String name,int age){ this.name=name; this.age=age; System.out.println("call second constructor"); } public Object clone()throws { return super.clone(); } public boolean equals(Object o){ if(this==o)return true; if(! (o instanceof Customer)) return false; final Customer other=(Customer)o; if(this.name.equals(other.name) && this.age==other.age) return true; else return false; } public String toString(){ return "name="+name+",age="+age; } public static void main(String args[])throws Exception{//運用反射手段創(chuàng )建Customer對象 Class objClass=Class.forName("Customer"); Customer c1=(Customer)objClass.newInstance(); //會(huì )調用Customer類(lèi)的默認構造方法 System.out.println("c1: "+c1); //打印name=unknown,age=0//用new語(yǔ)句創(chuàng )建Customer對象 Customer c2=new Customer("Tom",20); System.out.println("c2: "+c2); //打印name=tom,age=20//運用克隆手段創(chuàng )建Customer對象 Customer c3=(Customer)c2.clone(); //不會(huì )調用Customer類(lèi)的構造方法 System.out.println("c2==c3 : "+(c2==c3)); //打印false System.out.println("c2.equals(c3) : "+c2.equals(c3)); //打印true System.out.println("c3: "+c3); //打印name=tom,age=20 } } 除了以上4種顯式地創(chuàng )建對象的方式以外,在程序中還可以隱含地創(chuàng )建對象,包括以下幾種情況:1.對于java命令中的每個(gè)命令行參數,Java虛擬機都會(huì )創(chuàng )建相應的String對象,并把它們組織到一個(gè)String數組中,再把該數組作為參數傳給程序入口main(String args[])方法。
2.程序代碼中的String類(lèi)型的直接數對應一個(gè)String對象。3.字符串操作符“+”的運算結果為一個(gè)新的String對象。
4.當Java虛擬機加載一個(gè)類(lèi)時(shí),會(huì )隱含地創(chuàng )建描述這個(gè)類(lèi)的Class實(shí)例.。
1. new一個(gè)對象
new ClassName();
2. 基本同上
Class.forName("className").newInstance();
3. 利用asm和cglib創(chuàng )建對象,不過(guò)這個(gè)對象在某些情況下有問(wèn)題,比如做為hibernate對象的時(shí)候
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ClassName);
enhancer.setCallback(NoOp.INSTANCE);
Object obj = enhancer.create();
4.克隆:clone()
聲明:本網(wǎng)站尊重并保護知識產(chǎn)權,根據《信息網(wǎng)絡(luò )傳播權保護條例》,如果我們轉載的作品侵犯了您的權利,請在一個(gè)月內通知我們,我們會(huì )及時(shí)刪除。
蜀ICP備2020033479號-4 Copyright ? 2016 學(xué)習?shū)B(niǎo). 頁(yè)面生成時(shí)間:2.763秒