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的数据类型