JAVA反射機制(一)

    JAVA反射機制是在運行狀態中,對於任意一個類,都能夠得到這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制.


    概括一下:


    反射就是讓你可以通過名稱來得到對象(類,屬性,方法)的技術。


    例如我們可以通過類名來生成一個類的實例;


    知道了方法名,就可以調用這個方法;知道了屬性名就可以訪問這個屬性的值。


    1、獲取類對應的Class對象


    運用(已知對象)getClass():Object類中的方法,每個類都擁有此方法。


    如: String str = new String();


    Class strClass = str.getClass();運用(已知子類的class) Class.getSuperclass():Class類中的方法,返回該Class的父類的Class;運用(已知類全名):Class.forName() 靜態方法運用(已知類): 類名.class


    2、通過類名來構造一個類的實例


    a、調用無參的構造函數:


    Class newoneClass = Class.forName(類全名); newoneClass.newInstance();


    b、調用有參的構造函數:我們可以自定義一個函數。


    public Object newInstance(String className, Object[] args) throws Exception {


    //args爲參數數組


    Class newoneClass = Class.forName(className); //得到參數的Class數組(每個參數的class組成的數組),由此來決定調用那個構造函數Class[] argsClass = new Class[args.length]; for (int i = 0, j = args.length; i < j; i++) { argsClass[i] = args[i].getClass();


    }


    Constructor cons = newoneClass.getConstructor(argsClass); //根據argsClass選擇函數return cons.newInstance(args); //根據具體參數實例化對象。


    }


    3、得到某個對象的屬性


    a、非靜態屬性:首先得到class,然後得到這個class具有的field,然後以具體實例爲參數調用這個field


    public Object getProperty(Object owner, String fieldName) throws Exception { Class ownerClass = owner.getClass();//首先得到class Field field = ownerClass.getField(fieldName); //然後得到這個class具有的field,也可以通過getFields()得到所有的field Object property = field.get(owner); //owner指出了取得那個實例的這個屬性值,如果這個屬性是非公有的,這裏會報IllegalAccessException。


    return property;


    }


    b、靜態屬性:


    只有最後一步不同,由於靜態屬性屬於這個類,所以只要在這個類上調用這個field即可Object property = field.get(ownerClass);


    4、執行某對象的方法


    public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception { Class ownerClass = owner.getClass(); //也是從class開始的//得到參數的class數組,相當於得到參數列表的類型數組,來取決我們選擇哪個函數。


    Class[] argsClass = new Class[args.length]; for (int i = 0, j = args.length; i < j; i++) { argsClass[i] = args[i].getClass();


    }


    //根據函數名和函數類型來選擇函數


    Method method = ownerClass.getMethod(methodName, argsClass); return method.invoke(owner, args);//具體實例下,具體參數值下調用此函數


    }


    5、執行類的靜態方法


    和上面的相似只是最後一行不需要指定具體實例


    return method.invoke(null, args);


    6、判斷是否爲某個類的實例


    public boolean isInstance(Object obj, Class cls) { return cls.isInstance(obj);


    }


    測試bean類:SimpleBean.java


    Java代碼


    package com.royzhou.bean;


    public class SimpleBean {


    private String name;


    private String[] hobby;


    public SimpleBean() {


    }


    public SimpleBean(String name, String[] hobby) { this.name = name; this.hobby = hobby;


    }


    public void setName(String name) {


    this.name = name;


    }


    public String getName() {


    return this.name;


    }


    public void setHobby(String[] hobby) {


    this.hobby = hobby;


    }


    public String[] getHobby() {


    return this.hobby;


    }


    public String toString() {


    String returnValue = super.toString() + "\n"; returnValue += "name:=" + this.name + "\n"; if(this.hobby != null) {


    returnValue += "hobby:";


    for(String s : this.hobby) { returnValue += s + ",";


    }


    returnValue += "\n";


    }


    return returnValue;


    }


    }


    package com.royzhou.bean;


    public class SimpleBean {


    private String name;


    private String[] hobby;


    public SimpleBean() {


    }


    public SimpleBean(String name, String[] hobby) { this.name = name; this.hobby = hobby;


    }


    public void setName(String name) {


    this.name = name;


    }


    public String getName() {


    return this.name;


    }


    public void setHobby(String[] hobby) {


    this.hobby = hobby;


    }


    public String[] getHobby() {


    return this.hobby;


    }


    public String toString() {


    String returnValue = super.toString() + "\n"; returnValue += "name:=" + this.name + "\n"; if(this.hobby != null) {


    returnValue += "hobby:";


    for(String s : this.hobby) { returnValue += s + ",";


    }


    returnValue += "\n";


    }


    return returnValue;


    }


    }


    反射測試類:ReflectTest.java


    Java代碼


    package com.royzhou.bean;


    import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;


    public class ReflectTest {


    public static void main(String[] args) throws Exception {


    Class clazz = SimpleBean.class;


    //使用無參構造函數實例化bean


    SimpleBean sb = (SimpleBean)clazz.newInstance(); System.out.println(sb);


    //使用有參構造函數實例化bean


    Constructor constructor = clazz.getConstructor(new Class[]{String.class, String[].class}); sb = (SimpleBean)constructor.newInstance(new Object[]{"royzhou",new String[]{"football","basketball"}}); System.out.println(sb);


    //爲name字段設置值


    Field field = clazz.getDeclaredField("name"); field.setAccessible(true); //避免private不可訪問拋出異常field.set(sb, "royzhou1985"); System.out.println("modify name using Field:=" + sb.getName() + "\n");


    //列出類SimpleBean的所有方法


    Method[] methods = clazz.getDeclaredMethods(); System.out.println("get methods of class SimpleBean:");


    for(Method method : methods) {


    if("setHobby".equals(method.getName())) {


    //動態調用類的方法來爲hobby設置值


    method.invoke(sb, new Object[]{new String[]{"tennis","fishing"}});


    }


    System.out.println(method.getName());


    }


    System.out.println("\nset by invoke Method"); System.out.println(sb);


    }


    }


    package com.royzhou.bean;


    import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;


    public class ReflectTest {


    public static void main(String[] args) throws Exception {


    Class clazz = SimpleBean.class;


    //使用無參構造函數實例化bean


    SimpleBean sb = (SimpleBean)clazz.newInstance(); System.out.println(sb);


    //使用有參構造函數實例化bean


    Constructor constructor = clazz.getConstructor(new Class[]{String.class, String[].class}); sb = (SimpleBean)constructor.newInstance(new Object[]{"royzhou",new String[]{"football","basketball"}}); System.out.println(sb);


    //爲name字段設置值


    Field field = clazz.getDeclaredField("name"); field.setAccessible(true); //避免private不可訪問拋出異常field.set(sb, "royzhou1985"); System.out.println("modify name using Field:=" + sb.getName() + "\n");


    //列出類SimpleBean的所有方法


    Method[] methods = clazz.getDeclaredMethods(); System.out.println("get methods of class SimpleBean:");


    for(Method method : methods) {


    if("setHobby".equals(method.getName())) {


    //動態調用類的方法來爲hobby設置值


    method.invoke(sb, new Object[]{new String[]{"tennis","fishing"}});


    }


    System.out.println(method.getName());


    }


    System.out.println("\nset by invoke Method"); System.out.println(sb);


    }


    }


    輸出結果:


    com.royzhou.bean.SimpleBean@757aef


    name:=null


    com.royzhou.bean.SimpleBean@d9f9c3


    name:=royzhou


    hobby:football,basketball,


    modify name using Field:=royzhou1985


    get methods of class SimpleBean:


    setHobby


    getHobby


    getName


    toString


    setName


    set by invoke Method


    com.royzhou.bean.SimpleBean@d9f9c3


    name:=royzhou1985


    hobby:tennis,fishing,
...


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章