Java反射機制概述

Reflection(反射)是被視爲動態語言的關鍵,反射機制容許程序在執行期 藉助於Reflection API取得任何類的內部信息,並能直接操做任意對象的內 部屬性及方法。java

加載完類以後,在堆內存的方法區中就產生了一個Class類型的對象(一個類只有一個Class對象),這個對象就包含了完整的類的結構信息。咱們能夠經過這個對象看到類的結構。這個對象就像一面鏡子,透過這個鏡子看到類的結構,因此,咱們形象的稱之爲:反射。mysql

正常方式: 引入須要的包名稱 → 經過new實例化對象 → 取得實例化對象
反射方式: 經過實例化對象 → getClass()方法 → 獲得完整的包名稱面試

Java反射機制提供的功能算法

在運行時判斷任意一個對象所屬的類。
在運行時構造任意一個類的對象。
在運行時判斷任意一個類所具備的成員變量和方法。
在運行時獲取泛型信息。
在運行時調用任意一個對象的成員變量和方法。
在運行時處理註解。
生成動態代理。spring

public class Person {
    private String name;
    public int age;
    public void show() {
        System.out.println("您好!世界");
    }
    private String showNation(String nation){
        System.out.println("個人國際是:" + nation);
        return nation;
    }
    private Person(String name) {
        this.name = name;
    }
    .....
}
public void test2() throws Exception {
    Class clazz = Person.class;
    // 1.經過反射,建立Person類的對象
    Constructor cons = clazz.getConstructor(String.class, int.class);
    Object obj = cons.newInstance("Tom", 12);
    Person p = (Person) obj;
    System.out.println(p.toString());
    // 2.經過反射,調用指定的屬性、方法、對象
    // 調屬性
    Field age = clazz.getDeclaredField("age");
    age.set(p,10);
    System.out.println(p.toString());
    // 調方法
    Method method = clazz.getDeclaredMethod("show");
    method.invoke(p);
    // 經過反射是能夠調用私有的屬性、方法、構造器
    // 調用私有構造器
    Constructor cons1 = clazz.getDeclaredConstructor(String.class);
    cons1.setAccessible(true);
    Person p1 = (Person) cons1.newInstance("Jerry");
    System.out.println(p1);
    // 調用私有方法
    Field name = clazz.getDeclaredField("name");
    name.setAccessible(true);
    name.set(p1,"Han");
    System.out.println(p1);
    // 調用私有方法
    Method method1 = clazz.getDeclaredMethod("showNation", String.class);
    method1.setAccessible(true);
    String invoke = (String) method1.invoke(p1, "中國");
    System.out.println(invoke);
}./*歡迎加入java交流Q君樣:909038429一塊兒吹水聊天

java.lang.Class類的理解
類的加載過程:程序通過java.exe命令之後,會生成一個或多個字節碼文件(.class),接着使用java.exe命令對字節碼進行解釋運行。至關與將某個字節碼文件加載到內存中,此過程稱爲類的加載。加載到內存中的類,咱們稱之爲運行時類,此運行時類,就做爲Class的一個實例。
Class的實例就是對應着一個運行時類。
加載到內存中的運行時類,會緩存必定的時間。在此時間以內,咱們能夠經過不一樣方式來獲取從運行時類。sql

// 獲取Class的實例的方法
public void test3() throws ClassNotFoundException {
    // 方式一:調用運行時類的屬性.class
    Class clazz1 = Person.class;
    // 方式二:經過運行時類的對象
    Person person = new Person();
    Class clazz2 = person.getClass();
    // 方法三:調用Class的靜態方法forName(String classPath)
    Class clazz3 = Class.forName("com.tyt.java.Person");
    // 方式四:類的加載器 ClassLoader
    ClassLoader classLoader = ReflectionTest.class.getClassLoader();
    Class clazz4 = classLoader.loadClass("com.tyt.java.Person");
    System.out.println(clazz1 == clazz2);
    System.out.println(clazz2 == clazz3);
    System.out.println(clazz3 == clazz4);
}

Class實例能夠是那些結構的說明:數組

public void test5() {
    Class c1 = Object.class;
    Class c2 = Comparable.class;
    Class c3 = String[].class;
    Class c4 = int[][].class;
    Class c5 = ElementType.class;
    Class c6 = Override.class;
    Class c7 = int.class;
    Class c8 = void.class;
    Class c9 = Class.class;

    int[] a = new int[10];
    int[] b = new int[100];
    Class c10 = a.getClass();
    Class c11 = b.getClass();
    // 只要數組元素類型與維度同樣,就是同一個Class
    System.out.println(c10 == c11);// true
}

使用Properties:用於讀取配置文件。緩存

// 目錄結構
// |--module
// |---stc
// |----com.tyt.java
// |-----PropertiesTest.java
// |-----jdbc1.properties
// |--jdbc.properties
public void test2() {
    String user = null;
    String passwored = null;
    FileInputStream inputStream = null;
    try {
        Properties properties = new Properties();
        // 讀取配置方式一:
        // inputStream = new FileInputStream("jdbc.properties");
        // properties.load(inputStream);
        // 讀取配置方式二:使用ClassLoader
        // 配置文件默認識別爲:當前module的src下
        ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
        InputStream inputStream1 = classLoader.getResourceAsStream("jdbc1.properties");
        properties.load(inputStream1);
        user = properties.getProperty("user");
        passwored = properties.getProperty("passwored");
        System.out.println("user = " + user + ",passwored = " + passwored);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

image
最新2020整理收集的一些高頻面試題(都整理成文檔),有不少乾貨,包含mysql,netty,spring,線程,spring cloud、jvm、源碼、算法等詳細講解,也有詳細的學習規劃圖,面試題整理等,須要獲取這些內容的朋友請加Q君樣:909038429
/./*歡迎加入java交流Q君樣:909038429一塊兒吹水聊天jvm

相關文章
相關標籤/搜索