1. 程式人生 > 實用技巧 >Java--反射的基礎用法

Java--反射的基礎用法

獲取Class物件

public class ReflectTarget {

    public static void main(String[] args) {
        //第1種方式
        ReflectTarget reflectTarget = new ReflectTarget();
        Class  class1 = reflectTarget.getClass();
        System.out.println("第1種:"+class1.getName());
        //第2種方式
        Class  class2 = ReflectTarget.class;
        System.out.println("第2種:"+class2.getName());
        //第3種方式
        Class  class3 = null;
        try {
            class3 = Class.forName("demo.reflect.ReflectTarget");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("第3種:"+class3.getName());
    }
}
第1種:demo.reflect.ReflectTarget
第2種:demo.reflect.ReflectTarget
第3種:demo.reflect.ReflectTarget

獲取構造方法並建立例項

/*
 * 通過Class物件可以獲取某個類中的:構造方法;
 *
 * 獲取構造方法:
 *         1).批量的方法:
 *             public Constructor[] getConstructors():所有"公有的"構造方法
              public Constructor[] getDeclaredConstructors():獲取所有的構造方法(包括私有、受保護、預設、公有)
 *         2).獲取單個的方法,並呼叫:
 *             public Constructor getConstructor(Class... parameterTypes):獲取帶參的"公有的"構造方法:
 *             public Constructor getDeclaredConstructor(Class... parameterTypes):獲取"某個構造方法"可以是私有的,或受保護、預設、公有;
 *
 *             呼叫構造方法:
 *             Constructor-->newInstance(Object... initargs)
 */
public class ConstructorCollector {
    public static void main(String[] args) throws Exception{
        Class  clazz = Class.forName("demo.reflect.ReflectTarget");
        System.out.println("==============獲取所有公有的構造方法==============");
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("==============獲取所有的構造方法(包括私有、受保護、預設、公有)==============");
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for (Constructor constructor : declaredConstructors) {
            System.out.println(constructor);
        }
        System.out.println("==============獲取帶參的公有的構造方法==============");
        Constructor publicConstructor = clazz.getConstructor(String.class, int.class);
        System.out.println(publicConstructor);
        System.out.println("==============獲取私有的構造方法==============");
        Constructor privateConstructor = clazz.getDeclaredConstructor(int.class);
        System.out.println(privateConstructor);
        System.out.println("==============呼叫私有的構造方法==============");
        /*暴力訪問(無視訪問修飾符)*/
        privateConstructor.setAccessible(true);
        ReflectTarget newInstance = (ReflectTarget) privateConstructor.newInstance(1);
        /*因此私有的單例物件也能通過反射創建出來*/
    }
}
==============獲取所有公有的構造方法==============
public demo.reflect.ReflectTarget(char)
public demo.reflect.ReflectTarget()
public demo.reflect.ReflectTarget(java.lang.String,int)
==============獲取所有的構造方法(包括私有、受保護、預設、公有)==============
protected demo.reflect.ReflectTarget(boolean)
private demo.reflect.ReflectTarget(int)
public demo.reflect.ReflectTarget(char)
public demo.reflect.ReflectTarget()
demo.reflect.ReflectTarget(java.lang.String)
public demo.reflect.ReflectTarget(java.lang.String,int)
==============獲取帶參的公有的構造方法==============
public demo.reflect.ReflectTarget(java.lang.String,int)
==============獲取私有的構造方法==============
private demo.reflect.ReflectTarget(int)
==============呼叫私有的構造方法==============
私有有1個參建構函式 i=1

獲取成員變數


/*
 * 獲取成員變數並呼叫:
 *
 * 1.批量的
 *      1).Field[] getFields():獲取所有的"公有欄位,包括父類的欄位"
 *      2).Field[] getDeclaredFields():獲取所有欄位,包括:私有、受保護、預設、公有,不包括父類的欄位;
 * 2.獲取單個的:
 *      1).public Field getField(String fieldName):獲取某個"公有的"欄位,包括父類的欄位;
 *      2).public Field getDeclaredField(String fieldName):獲取某個欄位(可以是私有的),不包括父類的欄位
 *
 *   設定欄位的值:
 *      Field --> public void set(Object obj,Object value):
 *                  引數說明:
 *                  1.obj:要設定的欄位所在的物件;
 *                  2.value:要為欄位設定的值;
 *
 */
public class FieldCollector {
    public static void main(String[] args) throws Exception{
        Class  clazz = Class.forName("demo.reflect.ReflectTarget");
        System.out.println("==============獲取所有公有欄位,包括父類的欄位==============");
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("==============獲取所有的欄位(包括私有、受保護、預設、公有,不包括父類的欄位)==============");
        Field[] declaredields = clazz.getDeclaredFields();
        for (Field field : declaredields) {
            System.out.println(field);
        }

        System.out.println("==============獲取某個公有的欄位,包括父類的欄位==============");
        Field s = clazz.getField("s");
        System.out.println("公有的欄位 s="+s);
        ReflectTarget reflectTarget = (ReflectTarget) clazz.getConstructor().newInstance();
        s.set(reflectTarget,"反射填充的字串");
        System.out.println("公有的欄位賦值後 s="+reflectTarget.s);

        System.out.println("==============獲取某個欄位(可以是私有的),不包括父類的欄位==============");
        Field i = clazz.getDeclaredField("i");
        System.out.println("私有的欄位 i="+i);
        /*暴力訪問(無視訪問修飾符)*/
        i.setAccessible(true);
        i.set(reflectTarget,1);
        System.out.println(reflectTarget);
    }
}
==============獲取所有公有欄位,包括父類的欄位==============
public java.lang.String demo.reflect.ReflectTarget.s
public java.lang.String demo.reflect.ReflectFartherTarget.fS
==============獲取所有的欄位(包括私有、受保護、預設、公有,不包括父類的欄位)==============
public java.lang.String demo.reflect.ReflectTarget.s
protected boolean demo.reflect.ReflectTarget.b
char demo.reflect.ReflectTarget.c
private int demo.reflect.ReflectTarget.i
==============獲取某個公有的欄位,包括父類的欄位==============
公有的欄位 s=public java.lang.String demo.reflect.ReflectTarget.s
公有無參建構函式
公有的欄位賦值後 s=反射填充的字串
==============獲取某個欄位(可以是私有的),不包括父類的欄位==============
私有的欄位 i=private int demo.reflect.ReflectTarget.i
ReflectTarget{s='反射填充的字串', b=false, c= , i=1}

獲取成員方法

/*
 * 獲取成員方法並呼叫:
 *
 * 1.批量的:
 *      public Method[] getMethods():獲取所有"公有方法";(包含了父類的方法也包含Object類)
 *      public Method[] getDeclaredMethods():獲取所有的成員方法,包括私有的(不包括繼承的)
 * 2.獲取單個的:
 *      public Method getMethod(String name,Class<?>... parameterTypes):
 *                  引數:
 *                      name : 方法名;
 *                      Class ... : 形參的Class型別物件
 *      public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
 *
 *   呼叫方法:
 *      Method --> public Object invoke(Object obj,Object... args):
 *                  引數說明:
 *                  obj : 要呼叫方法的物件;
 *                  args:呼叫方式時所傳遞的實參;
):
 */
public class MethodCollector {
    public static void main(String[] args)throws Exception {
        Class  reflectTargetClass = Class.forName("demo.reflect.ReflectTarget");
        System.out.println("==============獲取所有公有方法;(包含了父類的方法也包含Object類)==============");

        Method[] publicMethods = reflectTargetClass.getMethods();
        for (Method publicMethod : publicMethods) {
            System.out.println(publicMethod);
        }
        System.out.println("==============獲取所有的成員方法,包括私有的(不包括繼承的)==============");

        Method[] allMethods = reflectTargetClass.getDeclaredMethods();
        for (Method publicMethod : allMethods) {
            System.out.println(publicMethod);
        }
        System.out.println("==============獲取有參公有方法並執行==============");
        Method publicMethod = reflectTargetClass.getMethod("callPublic", String.class);
        ReflectTarget reflectTarget = (ReflectTarget) reflectTargetClass.getConstructor().newInstance();
        publicMethod.invoke(reflectTarget,"我是公用方法引數");

        System.out.println("==============獲取有參私有方法並執行,帶返回值==============");
        Method privateMethod = reflectTargetClass.getDeclaredMethod("callPrivate", int.class);
        privateMethod.setAccessible(true);
        String result = (String) privateMethod.invoke(reflectTarget, 1);
        System.out.println("執行私有方法callPrivate()返回值是 : "+result);
    }
}
==============獲取所有公有方法;(包含了父類的方法也包含Object類)==============
public static void demo.reflect.ReflectTarget.main(java.lang.String[])
public java.lang.String demo.reflect.ReflectTarget.toString()
public void demo.reflect.ReflectTarget.callPublic(java.lang.String)
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) 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()
==============獲取所有的成員方法,包括私有的(不包括繼承的)==============
public static void demo.reflect.ReflectTarget.main(java.lang.String[])
public java.lang.String demo.reflect.ReflectTarget.toString()
protected void demo.reflect.ReflectTarget.callProtected(java.lang.String)
void demo.reflect.ReflectTarget.callDefault()
private java.lang.String demo.reflect.ReflectTarget.callPrivate(int)
public void demo.reflect.ReflectTarget.callPublic(java.lang.String)
==============獲取有參公有方法並執行==============
公有無參建構函式
呼叫public方法callPublic,引數 s=我是公用方法引數
==============獲取有參私有方法並執行,帶返回值==============
呼叫private方法callPrivate()並有返回值,引數 i=1
執行私有方法callPrivate()返回值是 : 我是返回值1