【Java反射機制】_Class類的使用筆記
本章目標:
可以使用Class類完成對象的執行個體化操作
可以通過Constructor類調用有參構造方法完成對象的執行個體化操作
具體內容:
Class主要是反射的源頭,不光可以取得對象所在類的資訊,也可以直接通過Class類的方法進行對象的執行個體化操作正常情況下,使用關鍵字new 為對象執行個體化,如果現在已經執行個體化好了Class對象,則就可以通過Class類中提供的
public T new Instance()throws InstantiationException,IllegalAccessException
執行個體化對象
package org.lxh.demo15.instancedemo;class Person{ private String name; private int age; public void setName(String name){ this.name = name; } public void setAge(int age){ this.age = age; } public String getName(){ return this.name; } public int getAge(){ return this.age; } public String toString(){ return "姓名:"+this.name+",年齡:"+this.age; }}public class InstanceDemo01{ public static void main(String[] args){ Class<?> c = null; //聲明Class對象 try{ c = Class.forName("org.lxh.demo15.instancedemo.Person"); }catch(ClassNotFoundException e){ e.printStackTrace(); } Person per = null; //聲明Person對象 try{ per = (Person)c.newInstance(); }catch(Exception e){ e.printStackTrace(); } per.setName("李興華"); //設定姓名 per.setAge(30); //設定年齡 System.out.println(per); //內容輸出,調用toString }}
通過以上的代碼,可以發現,即使不使用關鍵字new對象也可以進行執行個體化操作,反射的作用。
但是,在使用以上操作的時候有一點必須注意,在操作中類中必須存在無參構造方法。否則無法執行個體化。
package org.lxh.demo15.instancedemo;class Person{ private String name; private int age; public Person(String name,int age){ this.setName(name); this.setAge(age); } public void setName(String name){ this.name = name; } public void setAge(int age){ this.age = age; } public String getName(){ return this.name; } public int getAge(){ return this.age; } public String toString(){ return "姓名:"+this.name+",年齡:"+this.age; }};public class InstanceDemo02{ public static void main(String args[]){ Class<?> c = null; try{ c = Class.forName("org.lxh.demo15.instancedemo.Person"); }catch(ClassNotFoundException e){ e.printStackTrace(); } Person per = null; //聲明person對象 try{ per = (Person)c.newInstance(); //執行個體化對象 }catch(Exception e){ e.printStackTrace(); } per.setName("牛兒吃草"); //設定姓名 per.setAge(30); //設定年齡 System.out.println(per); //內容輸出,調用toString }}
出現以下錯誤:
java.lang.InstantiationException:org.lxh.demo15.instancedemo.Person
所以說,發現,使用以上的方式實際上還是需要類中構造方法的支援,符合於對象的執行個體化要求。
如果要想解決這樣的的問題,則必須明確的指定要調用的構造方法,半傳遞參數。但是從實際的開發角度來講,一般使用反射執行個體化對象的時候,類中都最好存在一個無參構造,這樣的操作比較合理。
如果要想調用有參,則必須按照以下的步驟進行:
操作的注意:被執行個體化對象的類中必須存在無參構造方法,如果不存在的話,則肯定是無法執行個體化的。
對於以上的程式也並非沒有解決的方法,也是可以通過其他的方式進行執行個體化操作的,只是在操作的時候需要明確的調用類中的構造方法,並將參數傳遞進去之後才可以進行執行個體化操作,操作步驟如下:
1、通過Class類中的getConstructors()取得本類的全部構造方法。
2、向構造方法中傳遞一個對象數組進去,裡麵包含了構造方法中所需的各個參數。
3、之後通過Constructor執行個體化對象。
在Constructor類中存在一個方法:
public T newInstance(Object... initargs)
throws instantiationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
傳遞初始化參數,以進行對象的執行個體化操作。
明確調用有參構造,執行個體化對象:
package org.lxh.demo15.instancedemo;import java.lang.reflect.Constructor;class Person{ private String name; private int age; public Person(String name,int age){ this.setName(name); this.setAge(age); } public void setName(String name){ this.name = name; } public void setAge(int age){ this.age = age; } public String getName(){ return this.name; } public int getAge(){ return this.age; } public String toString(){ return "姓名:"+this.name+",年齡:"+this.age; }}public class InstanceDemo03{ public static void main(String args[]){ Class<?> c = null; try{ c = Class.forName("org.lxh.demo15.instancedemo.Person"); }catch(ClassNotFoundException e){ e.printStackTrace(); } Person per = null; //聲明Person對象 Constructor<?> cons[] = null; cons = c.getConstructors(); try{ per = (Person) cons[0].newInstance("李興華",30); //執行個體化對象 }catch(Exception e){ e.printStackTrace(); } System.out.println(per); //內容輸出,調用toString() }}
但是,從實際角度看,如果要使用反射進行對象的執行個體化操作,最好在類中存在無參構造。
總結:
1、本章的功能是Class用的最多的功能,而且在開發中使用者也會經常使用到的開發模式
2、在使用Class 執行個體化對象,必須保證類中存在一個無參構造,否則無法使用。
3、如果要想調用有參構造進行對象的執行個體化操作,則必須使用Constructor類完成,此類表示構造方法,並通過可變參數傳遞要求的內容。