反射
反射是將類抽象為一個Class對象。將類看成對象,分析它的構造方法,成員變量,方法以及內部類。
對類的分析,是將類抽象為Class對象;對構造方法的分析,是將構造方法抽象為Constructor類的對象;對成員變量的分析,是將變量抽象為Feild類的對象;對方法的分析,是將方法抽象為Method類的對象。
舉個例子:
1 public class Student { 2 public String name;//定義學生姓名 3 private int age;//定義學生年齡 4 private String sex;//定義學生性別 5 //獲得學生姓名的方法 6 public String getName() { 7 return name; 8 } 9 //學生姓名賦值的方法 10 public void setName(String name) { 11 this.name = name; 12 } 13 //獲得學生年齡的方法 14 public int getAge() { 15 return age; 16 } 17 //注意,這里沒有為學生年齡賦值的方法,學生年齡為私有類型。 18 19 //獲得學生性別的方法 20 public String getSex() { 21 return sex; 22 } 23 //學生性別賦值的方法 24 public void setSex(String sex) { 25 this.sex = sex; 26 } 27 }
1 public class Test { 2 public static void main(String[] args) { 3 Class<Student> clazz =Student.class; 4 try { 5 /Class Field Method的使用。 6 7 //獲得Student類的name屬性對象。 8 Field field1 = clazz.getDeclaredField("name"); 9 //返回name字段的修飾符 10 System.out.println(field1.getModifiers()); 11 //返回name字段的類型 12 System.out.println(field1.getType()); 13 //返回name字段的名稱 14 System.out.println(field1.getName()); 15 //獲得Student類的所有屬性對象。 16 Field[] field2 = clazz.getDeclaredFields(); 17 //遍歷所有屬性 18 for (Field field : field2) { 19 System.out.println(field.getName()); 20 System.out.println(field.getType()); 21 System.out.println(field.getModifiers()); 22 } 23 24 //為學生對象zhangsan沒有set方法的私有類型age賦值 25 Student zhangsan = new Student(); 26 //獲得age屬性的對象 27 Field age = clazz.getDeclaredField("age"); 28 //取消對age屬性的修飾符的檢查訪問,以便為age屬性賦值 29 age.setAccessible(true); 30 //為age屬性賦值 31 age.set(zhangsan, 18); 32 //回復對age屬性的修飾符的檢查訪問 33 age.setAccessible(false); 34 System.out.println(zhangsan.getAge()); 35 36 //Method 的使用 37 Method method1= clazz.getDeclaredMethod("getName"); 38 System.out.println(method1.getModifiers());
注解(Annotation)
注解的定義形式:
1 @interface 注解名{ 2 <成員類型> <成員名稱>() default "<默認值>"; 3 …… 4 }
下面這個例子定義了一個注解,注解名為MyAnotation,注解包含一個成員是int型的value()。@Retention表示注解的應用范圍,注解的應用范圍通常用RetentionPolicy中的枚舉常量表示,這個例子中用的RetentionPolicy中的RUNTIME常量,表示在運行時加載注解到虛擬機,有效的范圍最大。@Target表示次注解適用於變量類型,並且可為int類型的變量賦值。
此圖片摘自博客園的……@黑色幽默Lion
1 @Retention(RetentionPolicy.RUNTIME) 2 @Target(ElementType.FIELD) 3 public @interface MyAnotation { 4 int value(); 5 }
1 import java.lang.reflect.Field; 2 3 public class Student { 4 private String name; 5 @MyAnotation(value =18) 6 private int age; 7 Student(){ 8 Class clazz = Student.class; 9 try { 10 //獲取age屬性對象 11 Field field = clazz.getDeclaredField("age"); 12 //創建注解對象,獲取age屬性的注解 13 MyAnotation ma = field.getAnnotation(MyAnotation.class); 14 //判斷獲得的注解對象是否為空 15 if(ma!=null){ 16 //為age賦值 17 int i = ma.value(); 18 field.setAccessible(true); 19 field.set(this, i); 20 field.setAccessible(false); 21 } 22 } catch (NoSuchFieldException | SecurityException e) { 23 // TODO Auto-generated catch block 24 e.printStackTrace(); 25 } catch (IllegalArgumentException e) { 26 // TODO Auto-generated catch block 27 e.printStackTrace(); 28 } catch (IllegalAccessException e) { 29 // TODO Auto-generated catch block 30 e.printStackTrace(); 31 } 32 } 33 public String getName() { 34 return name; 35 } 36 public void setName(String name) { 37 this.name = name; 38 } 39 public int getAge() { 40 return age; 41 } 42 public void setAge(int age) { 43 this.age = age; 44 } 45 }