創建對象的幾種方式


 

 

1,new

Student s = new Student();

在堆儲存區開辟了一塊空間,其對象的引用存儲在棧存儲區上。

2,反射 reflect

java的反射機制是指,在運行狀態中,對於任意一個類,我們可以獲取這個類的屬性和方法,對於任意一個對象,我們可以調用這個對象的方法和屬性。這種動態獲取信息和動態調用對象的方法就是java 的反射機制。

Class 類,每個class 都會有一個Class對象,當我們完成一個類通過編譯之后,就會生成一個.class 文件,在生成的.class 文件中,就會有個Class 對象,用於表示這個類的類型信息。

 

獲得類的Class 對象的3中方法:

1,類名.class (任意數據類型,都會有一個class 屬性)

2,Class.forName("java.lang.String"); 類的全路徑

3,類的實例化對象下,有getClass() 方法。

 

 

反射創建對象:

 不存在有參的構造函數:

 方法1:

  類名.class.newInstance(); 就算沒有構造方法,也會調用默認的無參構造方法

  Demo newInstance = Demo.class.newInstance();
  newInstance.setUserName("chris");
  newInstance.setPassword("12345");
  System.out.println(newInstance.getUserName()+ newInstance.getPassword());

方法2: 

  和方法1本質相同,一個是使用類名.class ,一個是使用Class.forName("類的全路勁")來獲取類的類對象,再通過newInstance()方法創建對象。

  Class<Demo> clazz = (Class<Demo>) Class.forName("Demo");
  Demo newInstance2 = clazz.newInstance();
  newInstance2.setPassword("12345");
  newInstance2.setUserName("Sarah");
  System.out.println(newInstance2.getUserName()+ newInstance2.getPassword());

 

  存在有參的構造函數:

  先獲取類的Class 對象,通過類對象獲取到指定的構造器,可以是有參,可以是無參,通過指定的構造器,創建對象

  Class<Demo> clazz3 = (Class<Demo>) Class.forName("Demo");
  Constructor<Demo> con = clazz3.getDeclaredConstructor(String.class,String.class);
  Demo newInstance3 = con.newInstance("Mike","12345");
  //newInstance3.setUserName("vincent");可以通過反射是可以改變對象的值
  //newInstance3.setPassword("12345");
  System.out.println(newInstance3.getUserName()+ newInstance3.getPassword());

 

Class對象獲取構造器比較:

Constructor<Demo> con = clazz3.getDeclaredConstructor(String.class,String.class); //能獲取到指定參數的構造器,和訪問修飾符無關,private,public 所有的可以獲取到

Constructor<?>[] conn = clazz4.getConstructors();//所有public 修飾的構造器

Constructor<Demo> connn = clazz5.getConstructor(String.class,String.class);//所有public 修飾的帶參數的指定構造器

 

反射的應用場景:

jdbc的連接

Class.forName("com.mysql.jdbc.Driver")

springIOC反射創建對象

mybatis

 

3,clone

調用clone,jvm就會創建一個新的對象,將前面對象的內容全部拷貝進去。用clone方法創建對象並不會調用任何構造函數。

前提,必須要實現Cloneable 接口,本地實現 protected native Object clone() throws CloneNotSupportedException;

Demo clone = (Demo) newInstance.clone();

 

4,反序列化

序列化:將堆內存中的java 對象通過某種方式,存儲到磁盤上或者傳輸給其他網絡節點,也就是java對象轉成二進制。

反序列化:與序列化相反,再將序列化之后的二進制串再轉成數據結構或對象。

 

為什么需要做序列化?

1,網絡節點的傳輸,java 對象需要轉成二進制串。

2,服務器鈍化:如果在內存中,一個對象長時間沒有被調用,就會將其序列化存儲在本地磁盤上,有需要活動的時候,就會現在內存中尋找,找不到,會將磁盤上的二進制再次反序列化成java 對象。可以節省服務器內存。

 

實現序列化?

1,需要做序列化的對象的類,必須實現序列化接口:Java.lang.Serializable 接口

 

通過反序列化創建對象。

//本地創建a.txt 文件,並且把對象序列化轉成二進制寫進文件中

  

  File f = new File(String path)

  OutputStream op = new FileOutputStream(file);  

  ObjectOutputStream ops = new ObjectOutputStream(op);

  ops.writeObject(new Demo("Chris", "12345"));

   ops.close();

//從寫進的文件中,讀取二進制串,用對象流將其讀出

  InputStream in = new FileInputStream(file);

  ObjectInputStream os = new ObjectInputStream(in);

  Demo d = (Demo) os.readObject();

  System.out.println(d.getUserName()+ d.getPassword());

   os.close();

 

反序列化 請注意深復制和淺復制

https://www.cnblogs.com/pickKnow/p/11104193.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM