JAVA反射舉例

DoIt發表於2018-03-22

什麼是反射

Java反射機制是在執行狀態中,對於任意一個類,都能知道這個類的所以屬性和方法;對於任何一個物件,都能夠呼叫它的任何一個方法和屬性;這樣動態獲取新的以及動態呼叫物件方法的功能就叫做反射。
簡單來說反射就是解剖一個類,然後獲取這個類中的屬性和方法,前提是要獲取這個類的Class物件
在java中給我們提供了幾個這幾個類用於描述編譯後的各種物件
複製程式碼

如何使用反射

A . 使用Class類,獲取出被解剖的這個類的class檔案物件 
B . 使用Class類方法,獲取出類中的所有成員 
C . 將成員獲取出來後,交給對應類,對應類中的方法,執行成員
複製程式碼

如何獲取,class檔案物件

1、使用類的物件獲取

每個類都使用Object作為父類,Object類方法 getClass() 
返回這個類的class檔案物件,方法返回值Class型別物件
複製程式碼

2、使用類的靜態屬性獲取

類名.class 返回這個類的class檔案物件.屬性執行結果也是Class型別物件
複製程式碼

3、使用Class類的靜態方法獲取

Class類靜態方法 forName(String 類名) 傳遞字串類名 
獲取到這個類的class檔案物件,方法返回值也是Class型別物件
不管用哪種方式獲取的Class物件,他們都是相等的。
複製程式碼

類:

java.lang.Class ---> 描述編譯後的class檔案的物件
java.lang.reflect.Constructor ---> 用於描述構造方法
java.lang.reflect.Field ---> 描述欄位(成員變數)
java.lang.reflect.Method ---> 描述成員方法
複製程式碼

定義demo

package com.test.demo; /**

  • 定義person類 */ public class Person {

}

package com.test.demo;

public class ReflectTest { public static void main(String[] args) throws ClassNotFoundException {

    //第1種方式獲取Class物件

    Person p1=new Person();
    Class cc=p1.getClass();
    System.out.println(cc);

    //第2種方式獲取Class物件
    Class cc2=Person.class;
    System.out.println(cc2);
    //第3種方式獲取Class物件
    Class cc3=Class.forName("com.test.demo.Person");//全類名
    System.out.println(cc3);

    System.out.println(cc==cc2);
    System.out.println(cc2==cc3);
}
複製程式碼

}

//輸出結果 class com.test.demo.Person class com.test.demo.Person class com.test.demo.Person true true

獲取構造

為Person類增加構造

public Person(){ System.out.println("Person類無引數構造"); } public Person(int a,int b,String s){ System.out.println("Person類有引數構造:a:"+a+" b:"+b+" s:"+s); }

private Person(int a){
    System.out.println("Person類有引數   私有 構造:a:"+a);
}
複製程式碼

package com.test.demo;

import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;

public class ReflectTest { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    Class clazz=Person.class;
    //獲取Person類所有 公共 構造
    Constructor [] conarr=clazz.getConstructors();

    for(Constructor con :conarr){
        System.out.println(con);
    }
    //獲取指定構造方法
    //無引數
    Constructor cc=clazz.getConstructor();
    Object oo=cc.newInstance();

    //有引數
    Constructor cc2=clazz.getConstructor(int.class,int.class,String.class);
    Object oo2=cc2.newInstance(1,2,"haha");

    //獲取私有構造方法
    Constructor cc3=clazz.getDeclaredConstructor(int.class);
    //暴力訪問
    cc3.setAccessible(true);
    Object oo3=cc3.newInstance(1);

    clazz.newInstance();//直接獲取空引數構造,必須是public
}
複製程式碼

}

輸出結果

public com.test.demo.Person()

public com.test.demo.Person(int,int,java.lang.String)

Person類無引數構造

Person類有引數構造:a:1 b:2 s:haha

Person類有引數 私有 構造:a:1

Person類無引數構造

獲取成員變數

為Person類增加成員變數

public String name="smt";
private String idcard="1001u09t";

@Override
public String toString() {
    // TODO Auto-generated method stub
    return "name:"+name+"  idcard:"+idcard;
}
複製程式碼

package com.test.demo;

import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException;

public class ReflectTest { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {

    Class clazz = Person.class;
    Object obj = clazz.newInstance();
    // 獲取Person類所有 公共 成員變數
    Field[] fields = clazz.getFields();
    for(Field s:fields){
        System.out.println(s);
    }

    Field field=clazz.getField("name");

    field.set(obj, "haha");

    System.out.println(obj);

    Field field2=clazz.getDeclaredField("idcard");
    field2.setAccessible(true);
    field2.set(obj, "123456");
    System.out.println(obj);
}
複製程式碼

}

輸出結果

Person類無引數構造

public java.lang.String com.test.demo.Person.name

name:haha idcard:1001u09t

name:haha idcard:123456

獲取成員方法

為Person類增加成員方法

public void show(){
    System.out.println("show 空引數");
}
public void show(int a){
    System.out.println("show   a:"+a);
}   
private void show(String s){
    System.out.println("show   s:"+s);
}
複製程式碼

public class ReflectTest { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {

    Class clazz = Person.class;
    Object obj = clazz.newInstance();
    // 獲取Person類所有 公共 成員方法
    Method [] methods=clazz.getMethods();

    for(Method m:methods){
        System.out.println(m);
    }

    Method m=clazz.getMethod("show");
    m.invoke(obj);

    Method m1=clazz.getMethod("show",int.class);
    m1.invoke(obj,1);

    Method m2=clazz.getDeclaredMethod("show",String.class);
    m2.setAccessible(true);
    m2.invoke(obj,"smt");
}
複製程式碼

}

輸出結果:

Person類無引數構造

public java.lang.String com.test.demo.Person.toString()

public void com.test.demo.Person.show(int)

public void com.test.demo.Person.show()

public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException

public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException

public final void java.lang.Object.wait() throws java.lang.InterruptedException

public boolean java.lang.Object.equals(java.lang.Object)

public native int java.lang.Object.hashCode()

public final native java.lang.Class java.lang.Object.getClass()

public final native void java.lang.Object.notify()

public final native void java.lang.Object.notifyAll()

show 空引數

show a:1

show s:smt

反射在Android中的應用
設定選單中圖示的顯示

@Override public boolean onMenuOpened(int featureId, Menu menu) { if (featureId == Window.FEATURE_ACTION_BAR && menu != null) { if (menu.getClass().getSimpleName().equals("MenuBuilder")) { try { Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch (Exception e) { } } } return super.onMenuOpened(featureId, menu); }

相關文章