Field java.lang.reflect 表示一個字段html
public class ParentClass { private String s_pri_p = "parent_private"; protected String s_pro_p = "parent_protected"; String s_def_p = "parent_default"; public String s_pub_p = "parent_public"; private String sc_pri_p = "parent_static_private"; protected String sc_pro_p = "parent_static__protected"; String sc_def_p = "parent_static__default"; public String sc_pub_p = "parent_static__public"; }
public class SubClass extends ParentClass { private String s_pri = "private"; protected String s_pro = "protected"; String s_def = "default"; public String s_pub = "public"; private static String sc_pri = "private"; protected static String sc_pro = "protected"; static String sc_def = "default"; public static String sc_pub = "public"; public List<String> actual = null; public static void main(String[] args) { try { Class<?> clz = SubClass.class; SubClass sub = new SubClass(); Field[] fields = clz.getDeclaredFields();//獲取全部訪問權限爲public的成員變量 for (Field field : fields) { System.out.println("權限----"+field.getModifiers()+"--");//訪問權限 System.out.println("變量描述----"+field.toGenericString());//變量名稱 System.out.println("變量類型----"+field.getType().toString());//變量類型 System.out.println("變量真實類型----"+field.getGenericType());//變量真實類型 若是參數不是泛型的,與getType()結果相同 System.out.println("變量值----"+field.get(sub));//類SubClass實例sub的變量的值 System.out.println(); } } catch (Exception e) { e.printStackTrace(); } } }
運行結果: java
權限----2-- 變量描述----private java.lang.String cn.trip.core.servlet.SubClass.s_pri 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----private 權限----4-- 變量描述----protected java.lang.String cn.trip.core.servlet.SubClass.s_pro 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----protected 權限----0-- 變量描述----java.lang.String cn.trip.core.servlet.SubClass.s_def 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----default 權限----1-- 變量描述----public java.lang.String cn.trip.core.servlet.SubClass.s_pub 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----public 權限----10-- 變量描述----private static java.lang.String cn.trip.core.servlet.SubClass.sc_pri 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----private 權限----12-- 變量描述----protected static java.lang.String cn.trip.core.servlet.SubClass.sc_pro 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----protected 權限----8-- 變量描述----static java.lang.String cn.trip.core.servlet.SubClass.sc_def 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----default 權限----9-- 變量描述----public static java.lang.String cn.trip.core.servlet.SubClass.sc_pub 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----public 權限----1-- 變量描述----public java.util.List<java.lang.String> cn.trip.core.servlet.SubClass.actual 變量類型----interface java.util.List 變量真實類型----java.util.List<java.lang.String> 變量值----null
public class ParentClass { private String s_pri_p = "parent_private"; protected String s_pro_p = "parent_protected"; String s_def_p = "parent_default"; public String s_pub_p = "parent_public"; private String sc_pri_p = "parent_static_private"; protected String sc_pro_p = "parent_static__protected"; String sc_def_p = "parent_static__default"; public String sc_pub_p = "parent_static__public"; }
public class SubClass extends ParentClass { private String s_pri = "private"; protected String s_pro = "protected"; String s_def = "default"; public String s_pub = "public"; private static String sc_pri = "private"; protected static String sc_pro = "protected"; static String sc_def = "default"; public static String sc_pub = "public"; public List<String> actual = null; public static void main(String[] args) { try { Class<?> clz = SubClass.class; SubClass sub = new SubClass(); Field[] fields = clz.getFields();//獲取全部訪問權限爲public的成員變量 for (Field field : fields) { System.out.println("權限----"+field.getModifiers()+"--");//訪問權限 System.out.println("變量描述----"+field.toGenericString());//變量名稱 System.out.println("變量類型----"+field.getType().toString());//變量類型 System.out.println("變量真實類型----"+field.getGenericType());//變量真實類型 若是參數不是泛型的,與getType()結果相同 System.out.println("變量值----"+field.get(sub));//類SubClass實例sub的變量的值 System.out.println(); } } catch (Exception e) { e.printStackTrace(); } } }
運行結果:spa
權限----1-- 變量描述----public java.lang.String cn.trip.core.servlet.SubClass.s_pub 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----public 權限----9-- 變量描述----public static java.lang.String cn.trip.core.servlet.SubClass.sc_pub 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----public 權限----1-- 變量描述----public java.util.List<java.lang.String> cn.trip.core.servlet.SubClass.actual 變量類型----interface java.util.List 變量真實類型----java.util.List<java.lang.String> 變量值----null 權限----1-- 變量描述----public java.lang.String cn.trip.core.servlet.ParentClass.s_pub_p 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----parent_public 權限----1-- 變量描述----public java.lang.String cn.trip.core.servlet.ParentClass.sc_pub_p 變量類型----class java.lang.String 變量真實類型----class java.lang.String 變量值----parent_static__public
Field類的其餘方法:code
public String getName() 返回該字段定義的名稱
public Object get(Object obj); public boolean getBoolean(Object obj) public byte getByte(Object obj) public char getChar(Object obj) public short getShort(Object obj) public int getInt(Object obj) public long getLong(Object obj) public float getFloat(Object obj) 以上方法都是用來根據Field的類型獲取其的實際值,方法的參數obj 是類的實例。
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) 獲取該字段上指定類型爲annotationClass的註解
public Annotation[] getDeclaredAnnotations() 獲取該字段上全部聲明的註解
public Class<?> getDeclaringClass() 獲取該字段是由哪個類或接口聲明定義的,返回該類或者接口
public void set(Object obj,Object value) public void setBoolean(Object obj,boolean z) public void setByte(Object obj, byte b) public void setChar(Object obj, char c) public void setShort(Object obj, short s) public void setInt(Object obj,int i) public void setLong(Object obj,long l) public void setFloat(Object obj,float f) public void setDouble(Object obj,double d) 以上方法用於改變一個對象實例obj的Field字段的實際值,
關於訪問private字段,從新進行賦值htm
public class SubClass extends ParentClass { private String s_pri = "private"; protected String s_pro = "protected"; String s_def = "default"; public String s_pub = "public"; private static String sc_pri = "private"; protected static String sc_pro = "protected"; static String sc_def = "default"; public static String sc_pub = "public"; //public List<String> actual = null; public static void main(String[] args) { try { Class<?> clz = SubClass.class; SubClass sub = new SubClass(); Field[] fields = clz.getDeclaredFields();//獲取全部訪問權限爲public的成員變量 for (Field field : fields) { System.out.print("原來值---"+field.get(sub)+"---"); field.set(sub, "11"); System.out.println("修改後的值---"+field.get(sub)); } } catch (Exception e) { e.printStackTrace(); } } }
運行結果:對象
原來值---private---修改後的值---11 原來值---protected---修改後的值---11 原來值---default---修改後的值---11 原來值---public---修改後的值---11 原來值---private---修改後的值---11 原來值---protected---修改後的值---11 原來值---default---修改後的值---11 原來值---public---修改後的值---11
能夠看到能夠訪問private類型而且進行修改,再看下面代碼:接口
public class ClassTest { public static void main(String[] args) { try { Class<?> clz = SubClass.class; SubClass sub = new SubClass(); Field[] fields = clz.getDeclaredFields();//獲取全部訪問權限爲public的成員變量 for (Field field : fields) { System.out.print("原來值---"+field.get(sub)+"---"); field.set(sub, "11"); System.out.println("修改後的值---"+field.get(sub)); } } catch (Exception e) { e.printStackTrace(); } } }
運行結果:ip
java.lang.IllegalAccessException: Class cn.trip.core.servlet.ClassTest can not access a member of class cn.trip.core.servlet.SubClass with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:109) at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:261) at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:253) at java.lang.reflect.Field.get(Field.java:376) at cn.trip.core.servlet.ClassTest.main(ClassTest.java:15)
拋出訪問private類型變量的異常。 那麼二者結果爲何不同呢?get
這是由於這是兩個類的main方法,servlet
SubClass 本類中的main方法能訪問本類中private變量,所以沒有拋出異常; ClassTest 外部的類main方法沒有權限方法其餘類private變量,一次拋出訪問異常。 出現這種狀況應到調用Filed的setAccessible(boolean flag) 設置爲true,表示取消訪問檢查。
public class ClassTest { public static void main(String[] args) { try { Class<?> clz = SubClass.class; SubClass sub = new SubClass(); Field[] fields = clz.getDeclaredFields();//獲取全部訪問權限爲public的成員變量 for (Field field : fields) { field.setAccessible(true); System.out.print("原來值---"+field.get(sub)+"---"); field.set(sub, "11"); System.out.println("修改後的值---"+field.get(sub)); field.setAccessible(false); } } catch (Exception e) { e.printStackTrace(); } } }
運行結果:
原來值---private---修改後的值---11 原來值---protected---修改後的值---11 原來值---default---修改後的值---11 原來值---public---修改後的值---11 原來值---private---修改後的值---11 原來值---protected---修改後的值---11 原來值---default---修改後的值---11 原來值---public---修改後的值---11
public boolean equals(Object obj) { if (obj != null && obj instanceof Field) { Field other = (Field)obj; return (getDeclaringClass() == other.getDeclaringClass()) && (getName() == other.getName()) && (getType() == other.getType()); } return false; } Field類的equals方法 比較是不是同一個類聲明的Field,而後比較Field名稱、而後再比較Field的數據類型