field
在Java反射中Field用于获取某个类的属性或该属性的属性值
一:如何通过Field反射获取类的属性
Field提供如下几种方法:
1:Class.getDeclaredField(String name);
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段(包括私有成员)。
2:Class.getDeclaredFields();
返回 Field 对象的一个数组,该数组包含此 Class 对象所表示的类或接口所声明的所有字段(包括私有成员)。
3:Class.getField(String name);
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
4:Class.getFields();
返回一个包含某些 Field 对象的数组,该数组包含此 Class 对象所表示的类或接口的所有可访问公共字段。
下面一个例子说明如何通过Field反射获取类中的属性
我们先定义一个普通类Person
包含三个属性 公有name 私有age、sex
package com.mao.test;
public class Person
{
public String name;
private Integer age;
private String sex;
//省略所有属性的set、get方法
下面开始通过Field反射的各方法访问属性
package com.mao.test;
import java.lang.reflect.Field;
public class Test
{
public static void main(String[]args) throws NoSuchFieldException, SecurityException
{
Person person =new Person();
//通过Class.getDeclaredField(String name)获取类或接口的指定已声明字段。
Field f1=person.getClass().getDeclaredField("name");
System.out.println("-----Class.getDeclaredField(String name)用法-------");
System.out.println(f1);
System.out.println("-----Class.getDeclaredFields()用法-------");
//通过Class.getDeclaredFields()获取类或接口的指定已声明字段。
Field []f2=person.getClass().getDeclaredFields();
for(Field field:f2)
{
System.out.println(field);
}
System.out.println("-----Class.getField(String name)用法-------");
//通过Class.getField(String name)返回一个类或接口的指定公共成员字段,私有成员报错。
Field f3=person.getClass().getField("name");
System.out.println(f3);
//如果获取age属性(私有成员) 则会报错
//Field f3=person.getClass().getField("name");
System.out.println("-----Class.getFields()用法-------");
//通过Class.getField(),返回 Class 对象所表示的类或接口的所有可访问公共字段。
Field []f4=person.getClass().getFields();
for(Field fields:f4)
{
//因为只有name属性为共有,因此只能遍历出name属性
System.out.println(fields);
}
}
}
通过上面程序也可以发现Class.getField(String name)和Class.getFields()都只能返回公有属性,如果访问私有属性就会报错java.lang.NoSuchFieldException。
运行结果:
-----Class.getDeclaredField(String name)用法-------
public java.lang.String com.mao.test.Person.name
-----Class.getDeclaredFields()用法-------
public java.lang.String com.mao.test.Person.name
private java.lang.Integer com.mao.test.Person.age
private java.lang.String com.mao.test.Person.sex
-----Class.getField(String name)用法-------
public java.lang.String com.mao.test.Person.name
-----Class.getFields()用法-------
public java.lang.String com.mao.test.Person.name
二:获取属性的属性值并修改属性值
获取属性的值用get(Object obj)的方法,但是获取私有属性的时候必须先设置Accessible为true,然后才能获取。
下面咱们获取Person各属性的属性值并将姓名属性值修改
Test.java
package com.mao.test;
import java.lang.reflect.Field;
public class Test
{
public static void main(String[]args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
{
Person person =new Person();
person.setName("VipMao");
person.setAge(24);
person.setSex("男");
//通过Class.getDeclaredField(String name)获取类或接口的指定属性值。
Field f1=person.getClass().getDeclaredField("name");
System.out.println("-----Class.getDeclaredField(String name)用法-------");
System.out.println(f1.get(person));
System.out.println("-----Class.getDeclaredFields()用法-------");
//通过Class.getDeclaredFields()获取类或接口的指定属性值。
Field []f2=person.getClass().getDeclaredFields();
for(Field field:f2)
{
field.setAccessible(true);
System.out.println(field.get(person));
}
//修改属性值
System.out.println("----修改name属性------");
f1.set(person, "Maoge");
//修改后再遍历各属性的值
Field []f3=person.getClass().getDeclaredFields();
for(Field fields:f3)
{
fields.setAccessible(true);
System.out.println(fields.get(person));
}
}
}
从上面程序我们得知,通过get(Object obj)获取属性的值,通过set(Object obj,value)重新设置新的属性值,并且当我们需要获取私有属性的属性值得时候,我们必须设置Accessible为true,然后才能获取。
运行结果:
-----Class.getDeclaredField(String name)用法-------
VipMao
-----遍历属性值-------
VipMao
24
男
----修改name属性后再遍历属性值------
Maoge
24
男
转:https://blog.csdn.net/VipMao/article/details/51638547
另外附上
Field定义:
//AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。
public class AccessibleObject implements AnnotatedElement {
/*
* 1、实现了AnnotatedElement对注解支持的相关方法
* 2、提供访问控制
/
void setAccessible(boolean flag)
设置该对象(Field,Constructor,Method)是否可访问
boolean isAccessible()
该对象是否可访问
void setAccessible(AccessibleObject[] array, boolean flag)
设置这一组对象(Field,Constructor,Method)是否可访问
}
public interface Member{
public static final int PUBLIC = 0; //标识类或接口的所有已声明成员的集合。
public static final int DECLARED = 1; //标识类或接口的所有公共成员(包括继承成员)的集合。
public Class<?> getDeclaringClass();// 所在类
public String getName(); //返回此 Member 表示的底层成员或构造方法的简单名称。
public int getModifiers(); //作为整数返回由此 Member 所表示的成员或构造方法的 Java 语言修饰符。
public boolean isSynthetic(); //如果此成员是编译器引入的,则返回 true;否则,返回 false。
}
public final class Field extends AccessibleObject implements Member{
// 1.字段的设值和取值 ,对于静态属性,obj传null
set(Object obj, Object value)
setXX(Object obj, Object value) ,比如setInt,setBoolean
Object get(Object obj)
getXX(Object obj) ,比如getInt,getBoolean
// 2.字段上注解的获取
getDeclaredAnnotations()
getAnnotation(Class<T> annotationClass);
// 3.字段类型
Type getGenericType();
Class<?> getType();
// 4.字段修饰符
int modifer=field.getModifiers();
String modify = Modifier.toString(modifiers);
// 5.字段名称
String getName();
}
Field类实例
package reflect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.Arrays;
import java.util.List;
/**
* @author zhangquanit
*/
public class FieldTest {
private int mInt; // 普通成员变量
public static String mStr; // 静态成员变量
@MyAnnotation
private Object mObject; // 使用了注解的成员变量
private List<String> mList; // 泛型字段
public static void main(String[] args) throws Exception {
FieldTest obj = new FieldTest();
Class<? extends FieldTest> clazz = obj.getClass();
/*
* 普通属性字段的设置和获取
*/
Field normalField = clazz.getDeclaredField("mInt");
setAccessible(normalField);
String filedName=normalField.getName();//mInt
normalField.set(obj, 100); // 设值
int mIntValue = normalField.getInt(obj);// 取值 100;
/*
* 静态属性字段的设值和获取 (obj传null)
*/
Field staticField = clazz.getDeclaredField("mStr");
setAccessible(staticField);
staticField.set(null, "static value");
Object value = staticField.get(null);// static value
/*
* 字段的枚举相关操作 (更多相关信息参照 我写的 Java注解)
*/
Field annotationField = clazz.getDeclaredField("mObject");
setAccessible(annotationField);
Annotation[] declaredAnnotations = annotationField
.getDeclaredAnnotations();
System.out.println(Arrays.toString(declaredAnnotations));
/*
* 泛型字段
*/
Field genericField = clazz.getDeclaredField("mList");
setAccessible(genericField);
Type genericType = genericField.getGenericType();// java.util.List<java.lang.String>
Class type = genericField.getType(); // interface java.util.List
getActualType(genericType); //Class类型: class java.lang.String
}
// 私有的变量,需要设置为可访问
private static void setAccessible(Field field) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
}
// 获取List中泛型的实际类型
private static void getActualType(Type genericType) {
if (genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type actualType = parameterizedType.getActualTypeArguments()[0];
if (actualType instanceof TypeVariable) {// 泛型类型,比如T
TypeVariable typeVariable = (TypeVariable) actualType;
System.out.println("TypeVariable类型: " + typeVariable);
} else if (actualType instanceof WildcardType) {// 含通配符? 类型
WildcardType wildcardType = (WildcardType) actualType;
System.out.println("WildcardType类型: " + wildcardType);
} else if (actualType instanceof Class) { // 普通类对象
Class cls = (Class) actualType;
System.out.println("Class类型: " + actualType); // class
// java.lang.String
}
}
}
}
相关阅读
c语言strcpy()用法 strcpy,即string copy(字符串复制)的缩写。strcpy是一种C语言的标准库函数,strcpy把从src地址开始且含有’\0’结
大多商业软件,会对程序进行加密、加壳等安全措施以防范软件被破解,从而使得反编译越来越难。反编译是一个对目标可执行程序进行逆向
http://www.oschina.net/project/tag/167/code-confusion?lang=19&sort=view Java混淆器 ProGuard ProGuard 是一个免
主要讲解如何在java类中定义常量:/** * Method One */ interface ConstantInterface { String SUNDAY = "SUNDAY"; Stri
正如这段代码:Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show();Toast的用法很简单,通过静态方法makeText()创