Java中建立(執行個體化)對象的五種方式
1、用new語句建立對象,這是最常見的建立對象的方法。
2、通過Factory 方法返回對象,如:String str = String.valueOf(23);
3、運用反射手段,調用java.lang.Class或者java.lang.reflect.Constructor類的newInstance()執行個體方法。如:Object obj = Class.forName("java.lang.Object").newInstance();
4、調用對象的clone()方法。
5、通過I/O流(包括還原序列化),如運用還原序列化手段,調用java.io.ObjectInputStream對象的 readObject()方法。
package org.whb.test.demo724;/* *測試Cloneable介面的使用 *包含第一種和第三種方法clone() *不過要注意在clone()中深複製和潛複製的理解 *執行個體化對象 */class Person implements Cloneable{ private String name; private int age; public Person( String name,int age) { this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name){ this.name =name; } @Override public Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } @Override public String toString() { // TODO Auto-generated method stub return "姓名是:"+name+"; 年齡是:"+age; } }public class TestClone{ public static void main(String[] args){ Person p1 = new Person("王豪博",25); System.out.println(p1); Person p2 =null; try { p2 = (Person)p1.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } p2.setName("春香"); p2.setAge(24); System.out.println(p2); }}
/* *通過反射對對象進行初始化 *注意必須有無參數的Constructor *執行個體化Class類然後調用newInstance()方法 * */package org.whb.test.demo715;class Person{ private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString(){ return "年齡是:"+this.age+" 姓名是:"+this.name; } }public class TestClass { public static void main(String[] args){ Class< ?> c1 = null; try{ c1 = Class.forName("org.whb.test.demo715.Person"); }catch(ClassNotFoundException e){ e.printStackTrace(); } Person p1 = null; try { p1 =(Person)c1.newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } p1.setAge(12); p1.setName("haobo"); System.out.println(p1); }}
package org.whb.test.demo724;import java.io.*; import java.util.Date;/** * 對象的序列化和還原序列化測試類別. *1、序列化是幹什麼的。簡單說就是為了儲存在記憶體中的各種對象的狀態(也就是執行個體變數,不是方法),並且可以把儲存的對象狀態再讀出來。雖然你可以用你自 己的各種各樣的方法來儲存object states,但是Java給你提供一種應該比你自己好的儲存對象狀態的機制,那就是序列化。*2、什麼情況下需要序列化 a)當你想把的記憶體中的對象狀態儲存到一個檔案中或者資料庫中時候;b)當你想用通訊端在網路上傳送對象的時候;c)當你想通過RMI傳輸對象的時候;**3、相關注意事項a)序列化時,只對對象的狀態進行儲存,而不管對象的方法;b)當一個父類實現序列化,子類自動實現序列化,不需要顯式實現Serializable介面;c)當一個對象的執行個體變數引用其他對象,序列化該對象時也把引用對象進行序列化;d)並非所有的對象都可以序列化,,至於為什麼不可以,有很多原因了,比如:1.安全方面的原因,比如一個對象擁有private,public等field,對於一個要傳輸的對象,比如寫到檔案,或者進行rmi傳輸 等等,在序列化進行傳輸的過程中,這個對象的private等域是不受保護的。2. 資源分派方面的原因,比如socket,thread類,如果可以序列化,進行傳輸或者儲存,也無法對他們進行重新的資源分 配,而且,也是沒有必要這樣實現。*/public class ObjectSaver { public static void main(String[] args) throws Exception { ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream("D:/objectFile.swf")); //序列化對象 Customer customer = new Customer("haobo", 24); out.writeObject("你好!"); out.writeObject(new Date()); out.writeObject(customer); out.writeInt(123); //寫入基本類型資料 out.close(); //還原序列化對象 ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/objectFile.swf")); System.out.println("obj1=" + (String) in.readObject()); System.out.println("obj2=" + (Date) in.readObject()); Customer obj3 = (Customer) in.readObject(); System.out.println("obj3=" + obj3); int obj4 = in.readInt(); System.out.println("obj4=" + obj4); in.close(); } } class Customer implements Serializable { /** * */ private static final long serialVersionUID = -88175599799432325L; private String name; private int age; public Customer(String name, int age) { this.name = name; this.age = age; } public String toString() { return "name=" + name + ", age=" + age; } } /* * obj1=你好!obj2=Sat Jul 24 21:18:19 CST 2010obj3=name=haobo, age=24obj4=123 */
Java中,類的執行個體化方法有四種途徑:
1)使用new操作符
2)調用Class對象的newInstance()方法
3)調用clone()方法,對現有執行個體的拷貝
4)通過ObjectInputStream的readObject()方法還原序列化類
1.ClassInstance.java
1 import java.io.*; 2 3 class ClassInstance implements Cloneable, Serializable { 4 private String str = "測試..."; 5 public void fun(){ 6 System.out.println(str); 7 } 8 public ClassInstance(String str){ 9 System.out.println("有參類的執行個體化");10 this.str += str; 11 }12 public ClassInstance(){13 System.out.println("無參類的執行個體化");14 }15 public Object clone(){16 return this;17 }18 }
2.ClassInstanceTest.java
1 import java.io.*; 2 import java.lang.reflect.*; 3 4 public class ClassInstanceTest{ 5 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, 6 IllegalAccessException, IOException,InvocationTargetException, NoSuchMethodException{ 7 //第一種類的執行個體化方式 8 ClassInstance ci01 = new ClassInstance("01"); 9 ci01.fun();10 11 //第二種類的執行個體化方式12 ClassInstance ci02 = (ClassInstance) Class.forName("ClassInstance").newInstance();13 ci02.fun();14 15 //第三種類的執行個體化方式16 ClassInstance ci03 = (ClassInstance) ci01.clone();17 ci03.fun();18 19 //第四種類的執行個體化方式20 FileOutputStream fos = new FileOutputStream("ci.tmp");21 ObjectOutputStream oos = new ObjectOutputStream(fos);22 oos.writeObject(ci01);23 oos.close();24 fos.close();25 26 FileInputStream fis = new FileInputStream("ci.tmp");27 ObjectInputStream ois = new ObjectInputStream(fis);28 29 ClassInstance ci04 = (ClassInstance) ois.readObject();30 ois.close();31 fis.close();32 33 ci04.fun();34 System.out.println("--------------------額外測試--------------------");35 ClassInstance ci05 = null;36 //額外的思考 在第二種類執行個體化的方式中有沒有一種方法實現有參數的構造方式37 //獲得類的構造資訊38 Constructor[] ctor = Class.forName("ClassInstance").getDeclaredConstructors();39 //找到我們需要的構造方法40 for(int i=0;i<ctor.length;i++ ){41 Class[] cl = ctor[i].getParameterTypes();42 if(cl.length == 1){43 //執行個體化對象44 ci05 = (ClassInstance) Class.forName("ClassInstance").getConstructor(cl).newInstance(new Object[]{"05"});45 }46 }47 ci05.fun();48 }49 }
3.輸出結果
1 有參類的執行個體化2 測試...013 無參類的執行個體化4 測試...5 測試...01