反射机制2,Class类的使用
class是反射源頭,不光可以取得對象所在類信息,也可直接通過class類的方法進行對象的實例化操作。
使用關鍵字new為對象實例化。如果已經實例化好了class對象,就可以通過class類中提供的newInstance()操作?
public T newInstance()throws InstantiationException,IllegalAccessException來個例子:
package 類集;class Person{private String name ; // name屬性private int age ; // 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(){ // 覆寫toString()方法return "姓名:" + this.name + ",年齡:" + this.age ;} }; public class test1{public static void main(String args[]){ Class<?> c = null ; // 聲明Class對象try{ c = Class.forName("類集.Person") ;}catch(ClassNotFoundException e){e.printStackTrace() ;}Person per = null ; // 聲明Person對象try{per = (Person)c.newInstance() ; // 實例化對象}catch(Exception e){e.printStackTrace() ;}per.setName("小明") ; // 設置姓名per.setAge(23) ; // 設置年齡System.out.println(per) ; // 內容輸出,調用toString() } }返回結果:
姓名:小明,年齡:23上面的newInstance返回的類型是一個泛型,但是Class<?> c可知,這個類型是一個“?”,實際上是一個object類型,
所以需要向下轉型,(Person)c.newInstance()。
通過以上代碼發(fā)現,即使不使用new關鍵字也能進行實例化操作,反射作用。
但是,使用以上操作,必須注意:在操作中,類中必須存在無參構造方法。否則無法實例化。
例如:
package 類集;class Person{private String name ; // name屬性private int age ; // 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(){ // 覆寫toString()方法return "姓名:" + this.name + ",年齡:" + this.age ;} }; public class test1{public static void main(String args[]){Class<?> c = null ; // 聲明Class對象try{c = Class.forName("類集.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: 類集.Personat java.lang.Class.newInstance(Class.java:427)at 類集.test1.main(test1.java:36) Caused by: java.lang.NoSuchMethodException: 類集.Person.<init>()at java.lang.Class.getConstructor0(Class.java:3082)at java.lang.Class.newInstance(Class.java:412)... 1 more Exception in thread "main" java.lang.NullPointerExceptionat 類集.test1.main(test1.java:40)所以發(fā)現,使用以上方式,實際上還是需要無參構造方法的支持。符合于對象實例化要求。(實際上跟正常實例化new 類()方式一樣,調用構造方法)。
要想解決這樣問題,則必須明確指定要調用的構造方法,并且傳遞參數。從實際開發(fā)角度,一般使用反射實例化對象的時候,類中最好存在一個無參構造,比較合理。
?
操作步驟如下:
1,通過class類中的getConstructors()取得本類中全部構造方法,返回的結果是一個數組,見下面例子,
2,向構造方法中傳遞一個對象數組進去,里面保護構造方法所需要的各個參數。
3,之后通過Constructor實例化對象。
在constructor類中存在方法newInstance(),
public T newInstance(Object... initargs)throws InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException傳遞初始化參數,以進行對象的實例化操作。
明確調用有參構造,實例化對象。
package 類集;import java.lang.reflect.Constructor;class Person{private String name ; // name屬性private int age ; // 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(){ // 覆寫toString()方法return "姓名:" + this.name + ",年齡:" + this.age ;} }; public class test1{public static void main(String args[]){Class<?> c = null ; // 聲明Class對象try{ c = Class.forName("類集.Person") ;}catch(ClassNotFoundException e){e.printStackTrace() ;}Person per = null ; // 聲明Person對象Constructor<?> cons[] = null ;//返回的是一個數組。cons = c.getConstructors() ;//取得所有構造方法try{per = (Person)cons[0].newInstance("校華",18) ; // 實例化對象,因為只有一個構造方法,所以使用第一個構造方法,也就是cons[0],通過newInstance("",“”)傳給構造方法別忘了后面還要向下轉型,因為返回結果是object類型。}catch(Exception e){e.printStackTrace() ;}System.out.println(per) ; // 內容輸出,調用toString() } }
運行結果:
姓名:校華,年齡:18注意:接收的原理如下:
但是,如果要使用反射進行對象的實例化操作,最好在類中存在無參數構造。
?
總結:
1,本周功能是class用的最多的功能,而且開發(fā)中也會經常用到的模式
2,在使用class實例化對象的時候,必須保證類中存在無參構造,否則無法使用。
3,如果要想調用有參構造進行對象的實例化操作,必須使用constructor類完成,此類表示構造方法,并通過可變參數傳遞要求的內容。
總結
以上是生活随笔為你收集整理的反射机制2,Class类的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】C#调用WebService实例和
- 下一篇: Hangfire 任务调度