首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 反射機制深度解析與實戰示例

     編輯:Java 相關知識

什麼是 Java 反射?

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

簡單來說,一個類包含成員變量、方法、構造方法等組成部分。反射就是加載類,並解析出類的各個組成部分。

獲取 Class 對象的三種方式

在 Java 中,Class 類用於表示某個類的字節碼。獲取 Class 對象主要有三種途徑:

  1. Class.forName("全限定類名"):最常用,根據類的全限定名加載字節碼到內存,返回 Class 對象。
  2. 類名.class:通過類的 class 屬性獲取,編譯時期就確定,性能最好。
  3. 對象.getClass():通過類的實例對象調用 getClass() 方法獲取。

代碼示例

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        // 方式一:Class.forName()
        Class clazz = Class.forName("dsa.Person");

        // 方式二:對象.getClass()
        Class clazz1 = new Person().getClass();

        // 方式三:類名.class
        Class clazz2 = Person.class;
    }
}

反射構造方法

通過 Constructor 類可以獲取類的構造方法並實例化對象。

  • getConstructor(Class... parameterTypes):獲取指定參數類型的 public 構造方法。
  • getDeclaredConstructor(Class... parameterTypes):獲取指定參數類型的 所有聲明 構造方法(包含 private)。
  • 對於私有構造方法,需調用 setAccessible(true) 進行「暴力破解」後才能調用。

Person 類定義

public class Person {
    public Person() { System.out.println("無參構造"); }
    public Person(String name) { System.out.println(name); }
    public Person(String name, int pwd) { System.out.println(name + "+" + pwd); }
    private Person(List list) { System.out.println("List"); }
}

測試代碼

@Test
public void testPublicNoArg() throws Exception {
    Class clazz = Class.forName("ReflectDemo.Person");
    Constructor cr = clazz.getConstructor(null);
    Person p = (Person) cr.newInstance(null);
}

@Test
public void testPublicWithArgs() throws Exception {
    Class clazz = Class.forName("ReflectDemo.Person");
    Constructor cr = clazz.getConstructor(String.class);
    Person p = (Person) cr.newInstance("haha");
}

@Test
public void testPrivateConstructor() throws Exception {
    Class clazz = Class.forName("ReflectDemo.Person");
    Constructor cr = clazz.getDeclaredConstructor(List.class);
    cr.setAccessible(true); // 暴力破解
    Person p = (Person) cr.newInstance(new ArrayList());
}

反射普通方法

通過 Method 類調用類的方法:

  • getMethod(String name, Class... parameterTypes):獲取 public 方法(包含繼承)。
  • getDeclaredMethod(String name, Class... parameterTypes):獲取聲明的方法(不包含繼承,可獲取 private)。
  • 調用時使用 invoke(Object obj, Object... args),靜態方法傳 null 作為對象。

代碼示例

// 反射 public void jf()
Method method = clazz.getMethod("jf", null);
method.invoke(p, null);

// 反射 public static void jf(int num)
Method method = clazz.getMethod("jf", int.class);
method.invoke(null, 30); // 靜態方法對象傳 null

// 反射 private 方法
Method method = clazz.getDeclaredMethod("jf", InputStream.class);
method.setAccessible(true);
method.invoke(p, new FileInputStream("d:\\qqClient.txt"));

反射字段(Field)

通過 Field 類操作類的成員變量:

  • getField(String name):獲取 public 字段(包含繼承)。
  • getDeclaredField(String name):獲取聲明的字段(包含 private,不包含繼承)。
  • 操作私有字段需 setAccessible(true)。
  • 靜態字段操作時對象參數傳 null。

代碼示例

// public 字段
Field f = clazz.getField("name");
Object value = f.get(p);
f.set(p, "newName");

// private 字段
Field f = clazz.getDeclaredField("password");
f.setAccessible(true);
f.set(p, 36);

// private static 字段
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
f.set(null, 24); // 靜態字段對象傳 null

總結

反射機制雖然強大,但會破壞封裝性,且有一定性能開銷。實際開發中常用於框架設計(如 Spring、MyBatis)、註解處理、動態代理等場景。掌握反射的核心 API(Class、Constructor、Method、Field)及其獲取與調用方式,是 Java 進階開發的必備技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved