一、什麼是反射?
反射庫(Reflection Library)提供了一個非常豐富且精心設計的工具集,以便編寫能夠動態操縱Java程式碼的程式。這項功能被大量地應用在JavaBeans中,它是Java元件的體系結構(有關Java Beans的詳細內容見Java II卷)。使用反射,Java可以支援Visual Basic 使用者習慣使用的工具。特別是再設計或執行中新增新類時,能夠快速地應用開發工具動態地查詢新新增類的能力。
能夠分析類能力的程式成為反射(Reflective)。反射機制的功能極其強大,在下面可以看到,反射機制可以用來:
①在執行中分析類的能力
②在執行中檢視類物件,例如,編寫一個toString()方法提供所有類使用
③實現通用陣列操作程式碼
④利用Method物件,這個物件很像C++中的函式指標。
反射是一種功能強大且複雜的機制。使用它的主要人員是工具構造者,而不是應用程式設計師。
-----《Java核心技術卷 I 基礎知識》
(手打)
二、引用的類與庫
庫:java.lang.reflect.*
類:
① Class [Java.lang.Class]
② Field [java.lang.reflect.Field]
③ Method [java.lang.reflect.Method]
④ Constructor [java.lang.reflect.Constructor ]
⑤ Modifier [java.lang.reflect.Modifier]
⑥ AccessibleObject [java.lang.reflect.AccessibleObject]
三、常用方法總結
四、反射例項[測試]
1 /** 2 * @author:Johnny Zen 3 * @date:2017-06-09 4 * @description:一個實體類(Person) 5 **/ 6 import java.lang.reflect.Field; 7 8 import javax.activation.FileDataSource; 9 10 import com.sun.org.apache.bcel.internal.generic.NEW; 11 12 public class Person extends Entity{ 13 private String name; 14 private String password; 15 private String sex; 16 public String telephone; 17 18 public Person() { 19 this.name = "測試名字:哇哈哈"; 20 this.password = "測試密碼:783234"; 21 this.sex = "測試性別:男"; 22 this.telephone = "測試電話:2947298569365"; 23 } 24 25 public Person(String name, String password, String sex, String telephone) { 26 super(); 27 this.name = name; 28 this.password = password; 29 this.sex = sex; 30 this.telephone = telephone; 31 } 32 33 public String getName() { 34 return name; 35 } 36 37 public void setName(String name) { 38 this.name = name; 39 } 40 41 public String getPassword() { 42 return password; 43 } 44 45 public void setPassword(String password) { 46 this.password = password; 47 } 48 49 public String getSex() { 50 return sex; 51 } 52 53 public void setSex(String sex) { 54 this.sex = sex; 55 } 56 57 public String getTelephone() { 58 return telephone; 59 } 60 61 public void setTelephone(String telephone) { 62 this.telephone = telephone; 63 } 64 65 @Override 66 public String toString() { 67 return "Person [name=" + name + ", password=" + password + ", sex=" + sex + ", telephone=" 68 + telephone + "]"; 69 } 70 71 72 73 } 74 75 abstract class Entity{ 76 77 }
然後測試:
1 public static void main(String args[]) throws IllegalAccessException{ 2 3 Person person1 = new Person("王華","123456","男","15902848904"); 4 Person person2 = new Person(); 5 Person person3 = new Person(); 6 try { 7 System.out.println("對getClass()所有方法的遍歷:"); 8 System.out.println("person1.getClass().desiredAssertionStatus():"+person1.getClass().desiredAssertionStatus()); //期望的斷言狀態 9 10 System.out.println("person1.getClass().equals(person2):"+person1.getClass().equals(person2)); 11 System.out.println("person1.getClass().equals(person1):"+person1.getClass().equals(person1)); 12 System.out.println("person2.getClass().equals(person3):"+person2.getClass().equals(person3)); 13 14 System.out.println("person1.getClass().getCanonicalName():"+person2.getClass().getCanonicalName());//獲取權威正規的類名 15 16 System.out.println("person1.getClass().getModifiers():"+person1.getClass().getModifiers()); 17 System.out.println("person1.getClass().getName():"+person1.getClass().getName()); 18 System.out.println("person1.getClass().getSimpleName():"+person1.getClass().getSimpleName()); 19 System.out.println("person1.getClass().getTypeName():"+person1.getClass().getTypeName()); 20 21 System.out.println("person1.getClass().hashCode():"+person1.getClass().hashCode());//獲取該類的hashcode值 22 System.out.println("person2.getClass().hashCode():"+person2.getClass().hashCode()); 23 System.out.println("person3.getClass().hashCode():"+person3.getClass().hashCode()); 24 25 System.out.println("person1.getClass().toGenericString():"+person1.getClass().toGenericString()); 26 System.out.println("person1.getClass().toString():"+person1.getClass().toString()); 27 28 System.out.println("person1.getClass().isAnnotation():"+person1.getClass().isAnnotation()); //是否為註解型別 29 // System.out.println("【person1.getClass().asSubclass(null)】:"+person1.getClass().asSubclass(null)); //疑問? 30 // System.out.println("【person1.getClass().cast(person1)】:"+person1.getClass().cast(person1)); //疑問? 31 // System.out.println("person1.getClass().cast(person1):"+person1.getClass().cast(person1)); //疑問? 32 // System.out.println("person1.getClass().isAnnotationPresent(null):"+person1.getClass().isAnnotationPresent(null)); //疑問? 33 34 System.out.println("person1.getClass().isAnonymousClass():"+person1.getClass().isAnonymousClass()); //是否是匿名類 35 System.out.println("(new int[2]).getClass().isAnonymousClass():"+(new int[2]).getClass().isAnonymousClass()); //是否是匿名類 36 37 System.out.println("person1.getClass().isArray():"+person1.getClass().isArray()); //是否是陣列類 38 System.out.println("(new int[2]).getClass().isArray():"+(new int[2]).getClass().isArray()); //是否是陣列類 39 40 /*重點方法:getFields():*/ 41 System.out.println("***************************************************************************************************"); 42 System.out.println("person1.getClass().getFields()[0].getName():"+person1.getClass().getFields()[0].getName()); //獲取公共屬性的第(0+1)個屬性 43 44 Field fields1[] = person1.getClass().getFields(); //僅僅能獲取到public屬性的field 45 // System.out.println("fields1[1].get(person2):"+fields1[1].get(person2)); //由於第二個域獲取不到,域陣列長度為1,故產生陣列超界 46 Field fields2[] = person1.getClass().getDeclaredFields(); //獲取到所有宣告的field(包括private的) 47 System.out.println("fields2[1].get(person2):"+fields2[1].get(person2)); 48 System.out.println("fields2[1].get(person1):"+fields2[1].get(person1)); 49 50 System.out.println("fields2[1].getName():"+fields2[1].getName()); 51 System.out.println("fields2[1].hashCode():"+fields2[1].hashCode()); 52 System.out.println("fields2[1].toString():"+fields2[1].toString()); 53 54 System.out.println("fields2[1].equals(person2):"+fields2[1].equals(person2)); 55 System.out.println("fields2[1].equals(fields2[1]):"+fields2[1].equals(fields2[1]));//field是否相同 56 57 System.out.println("fields2[1].getType():"+fields2[1].getType());
58 System.out.println("fields[1].getType().getSimpleName()"+fields[1].getType().getSimpleName()); 59 } catch (Exception e) { 60 e.printStackTrace(); 61 // TODO: handle exception 62 } 63 64 65 }
結果:
1 對getClass()所有方法的遍歷: 2 person1.getClass().desiredAssertionStatus():false 3 person1.getClass().equals(person2):false 4 person1.getClass().equals(person1):false 5 person2.getClass().equals(person3):false 6 person1.getClass().getCanonicalName():Person 7 person1.getClass().getModifiers():1 8 person1.getClass().getName():Person 9 person1.getClass().getSimpleName():Person 10 person1.getClass().getTypeName():Person 11 person1.getClass().hashCode():914424520 12 person2.getClass().hashCode():914424520 13 person3.getClass().hashCode():914424520 14 person1.getClass().toGenericString():public class Person 15 person1.getClass().toString():class Person 16 person1.getClass().isAnnotation():false 17 person1.getClass().isAnonymousClass():false 18 (new int[2]).getClass().isAnonymousClass():false 19 person1.getClass().isArray():false 20 (new int[2]).getClass().isArray():true 21 *************************************************************************************************** 22 person1.getClass().getFields()[0].getName():telephone 23 fields2[1].get(person2):測試密碼:783234 24 fields2[1].get(person1):123456 25 fields2[1].getName():password 26 fields2[1].hashCode():-960414226 27 fields2[1].toString():private java.lang.String Person.password 28 fields2[1].equals(person2):false 29 fields2[1].equals(fields2[1]):true 30 fields2[1].getType():class java.lang.String
31 fields[1].getType().getSimpleName():String
五、參考文件