Java基础----反射Reflect---Field

     Field  java.lang.reflect  表示一个字段html

     在Java反射中,能够经过Class对象用如下几种方法获取Field:
    a、public Field[] getDeclaredFields()  只获取本类全部的字段  private、protected、default、public
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
   b、public Field[] getFields()   获取访问权限为public类型的字段 包括父类的public字段   
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
   c、public Field getDeclaredField(String name)  获取本类中指定参数名称的变量 不受访问权限约束
   d、public Field getField(String name)   获取指定参数名称的变量,该变量访问权限为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的数据类型
相关文章
相关标签/搜索