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

Java 反射深度解析:從類載入到動態代理的完整實戰指南

     編輯:Java 相關知識

前言

反射是 Java 動態性的基石,框架開發、動態代理、熱加載無不依賴它。本文通過 15+ 實戰案例,系統講解反射核心 API、類生命週期、動態代理與工廠模式應用。

案例速覽

  1. 獲取類全名:obj.getClass().getName()
  2. 三種獲取 Class 方式:Class.forName()、obj.getClass()、ClassName.class
  3. 實例化對象:無參構造器 clazz.newInstance()、有參構造器 constructor.newInstance(args)
  4. 獲取實現介面/父類/構造器/方法/欄位
  5. 動態調用方法:method.invoke(obj, args)
  6. 操作屬性(含私有):field.setAccessible(true)
  7. 陣列操作:Array.get/set、動態擴容
  8. 類載入器與雙親委派
  9. 動態代理:Proxy.newProxyInstance + InvocationHandler
  10. 類生命週期:載入→鏈接→初始化→使用→卸載
  11. 反射結合工廠模式:消除 if-else,支援屬性文件配置

核心知識點深度剖析

1. 類初始化順序

  • 靜態變量/靜態代碼塊:按代碼順序執行,僅執行一次(類載入時)。
  • 非靜態變量/非靜態代碼塊:按代碼順序執行,每次 new 都執行,優於構造器。
  • 構造器:最後執行。
  • 繼承鏈:父類靜態 → 子類靜態 → 父類非靜態 → 父類構造器 → 子類非靜態 → 子類構造器。

2. 靜態代碼塊 vs 非靜態代碼塊

static { /* 類載入時執行一次 */ }
{ /* 每次實例化前執行 */ }

3. 動態代理核心模式

public interface Subject { String say(String name, int age); }
public class RealSubject implements Subject { ... }

public class MyInvocationHandler implements InvocationHandler {
    private Object target;
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            this
        );
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 前置增強
        Object result = method.invoke(target, args);
        // 後置增強
        return result;
    }
}

應用:Spring AOP、RPC 框架、事務管理。

4. 反射優化工廠模式

傳統工廠需修改代碼新增產品;反射版只需配置類名:

public class Factory {
    public static Fruit getInstance(String className) {
        try {
            return (Fruit) Class.forName(className).newInstance();
        } catch (Exception e) { return null; }
    }
}

進階:結合 Properties 配置文件,實現零代碼修改擴展。

類生命週期完整流程

  1. 載入:類載入器讀取 .class 字節碼,生成 java.lang.Class 對象。
  2. 鏈接:
    • 驗證:字節碼合法性。
    • 準備:靜態變量分配內存、賦默認值。
    • 解析:符號引用 → 直接引用。
  3. 初始化:執行靜態變量賦值、靜態代碼塊。
  4. 使用:new 對象、調用方法。
  5. 卸載:無引用指向 Class 對象,GC 回收。

性能與安全提示

  • 反射調用比直接調用慢 10-100 倍,熱點路徑請緩存 Method/Constructor/Field。
  • setAccessible(true) 可能被 SecurityManager 禁止。
  • 模組化系統(JPMS)限制跨模組反射訪問,需 opens 宣告。

總結

反射賦予 Java 動態靈魂,掌握其核心 API、初始化順序、動態代理與類載入機制,是進階框架開發、源碼閱讀、疑難排查的必備內功。

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