嚴格說來,Java 非動態語言(運行時不可改變結構/類型)。但憑藉反射機制,Java 獲得了「半動態」能力:運行時加載、探知、使用編譯期未知的類,生成實例、調用方法、設置屬性。
Person p = new Student();
// 編譯時類型:Person | 運行時類型:Student
當編譯時無法預知對象真實類型(如外部傳入 Object,需調用其真實方法),反射成為必須手段。
java.lang.reflect)| 類 | 作用 |
|---|---|
Class | 反射核心,獲取類完整元數據(屬性、方法、構造器、註解等) |
Field | 表示成員變量,可讀寫屬性值(含私有) |
Method | 表示方法,可獲取信息或動態調用 |
Constructor | 表示構造方法,可動態創建實例 |
Class 對象的方式// 1. 對象.getClass()
Person p = new Person(); Class cla = p.getClass();
// 2. 類名.class
Class cls = Person.class;
// 3. Class.forName("全限定類名") —— 最常用,支援動態加載
Class cla = Class.forName("com.pb.Reflect.classinfo.Person");
Class cla = Class.forName("com.pb.Reflect.classinfo.Person");
// 獲取所有方法(含私有)
Method[] methods = cla.getDeclaredMethods();
for (Method m : methods) System.out.println(m.toString());
// 獲取所有屬性(含私有)
Field[] fields = cla.getDeclaredFields();
for (Field f : fields) System.out.println(f.toString());
// 獲取所有構造器(含私有)
Constructor[] ctors = cla.getDeclaredConstructors();
for (Constructor c : ctors) System.out.println(c.toString());
關鍵點:getDeclaredXxx() 獲取本類聲明的所有(含私有);getXxx() 僅獲取public 繼承的。
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge(int) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結束============ ========獲取成員構造方法信息============ private com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int) ========獲取成員構造方法信息結束============
Class 對象Class 方法獲取元數據(Field/Method/Constructor)field.set(obj, val)、method.invoke(obj, args)、ctor.newInstance(args)setAccessible(true) 可繞過訪問控制,但會破壞封裝,且受 SecurityManager 限制。module-info.java 中 opens 相關包才能深度反射。反射是框架級開發的基石(Spring、Hibernate、MyBatis 等大量依賴)。掌握 Class 獲取方式、四大核心 API、動態調用流程,並理解其性能/安全權衡,是進階 Java 開發者的必修課。