原來你是這樣的JAVA[06]-反射

1.JVM爲每個加載的class及interface創建了對應的Class實例來保存class及interface的所有信息;
獲取一個class對應的Class實例後,就可以獲取該class的所有信息;
通過Class實例獲取class信息的方法稱爲反射(Reflection);
JVM總是動態加載class,可以在運行期根據條件來控制加載class。

2.Java的反射API主要用於在運行過程中動態生成類、接口或對象等信息,其常用API如下。

  • Class類:用於獲取類的屬性、方法等信息。
  • Field類:表示類的成員變量,用於獲取和設置類中的屬性值。
  • Method類:表示類的方法,用於獲取方法的描述信息或者執行某個方法。
  • Constructor類:表示類的構造方法。
public class ReflectTest {
    public static void main(String[] args) {
        Class class1 = String.class;
        printClassInfo(class1);

        Class cls2 = "hello".getClass();
        printClassInfo(cls2);

        Class cls3 = String[].class;
        printClassInfo(cls3);

        //true,指向同一個實例
        System.out.println("class1 == cls2? "+(class1 == cls2));
    }

    private static void printClassInfo(Class c) {
        System.out.println("getName()=" + c.getName());
        System.out.println("getSimpleName()=" + c.getSimpleName());
        System.out.println("isInterface()=" + c.isInterface());
        System.out.println("isEnum()=" + c.isEnum());
        System.out.println("isArray()=" + c.isArray());
        System.out.println("isPrimitive=" + c.isPrimitive());
    }
}

3.Class類提供了以下幾個方法來獲取字段:

  • Field getField(name):根據字段名獲取某個public的field(包括父類)
  • Field getDeclaredField(name):根據字段名獲取當前類的某個field(不包括父類)
  • Field[] getFields():獲取所有public的field(包括父類)
  • Field[] getDeclaredFields():獲取當前類的所有field(不包括父類)
  • Field.setAccessible:成員變量爲private,必須進行此操作。
class Student extends Person {
    public int score;
    private int grade;
}

class Person {
    public String name;
}

首先嚐試訪問共有和私有變量:

private static void method() throws NoSuchFieldException {
        Class cls = Student.class;
        System.out.println(cls.getField("score"));
        System.out.println(cls.getDeclaredField("score"));
        //獲取私有方法報錯
//        System.out.println(cls.getField("grade"));
        System.out.println(cls.getDeclaredField("grade"));
    }

使用setAccessible,訪問私有成員變量:

private static void privateField() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        Class cls = Class.forName("com.cathyjava.j2se.reflect.Student");
        Student student = (Student) cls.getDeclaredConstructor().newInstance();
        Field field = cls.getDeclaredField("grade");
        field.setAccessible(true);
        field.set(student, 2);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章