超级通道: Java泛型学习系列-绪论
java.lang.reflect.Field类提供了用于获取和操作成员变量的静态方法。
1.通过Field可以做什么
通过Field可以做以下事情:
- Class对象与Field对象的相互获取
- 获取Field相关信息:修饰符Modifier、变量名、类型、注解Annotation
- 获取和修改Field的值
2.代码实例
实体类:
/**
* <p>用户表</p>
*
* @author hanchao 2018/2/14 22:30
*/
@MyAnnotationA
@MyAnnotationB
public class User extends SuperUser implements InterfaceAAA,InterfaceBBB {
@MyAnnotationA
@MyAnnotationB
public String username = "张三";
private int password = 123456;
//setter getter toString constructor...
}
实例类:
/**
* <p>java.lang.reflect.Field学习示例</p>
*
* @author hanchao 2018/2/26 21:23
*/
public class ReflectFieldDemo {
/**
* log4j
*/
private static final Logger LOGGER = Logger.getLogger(ReflectFieldDemo.class);
/**
* <p>Java反射-Field成员变量示例</p>
*
* @author hanchao 2018/2/26 21:26
*/
public static void main(String[] args) throws Exception {
LOGGER.info("Java反射-Field示例");
//首先获取Class的对象
Class userClass = User.class;
LOGGER.info("首先获取Class的对象:" + userClass + "\n");
LOGGER.info(" Class对象与Field对象的相互获取 //");
Class对象与Field对象的相互获取 //
//通过Class.getDeclaredField对象获取指定的Field对象
LOGGER.info("通过Class.getDeclaredField对象获取指定的Field对象");
Field usrFiled = userClass.getDeclaredField("username");
Field pwdFiled = userClass.getDeclaredField("password");
LOGGER.info("username的Field: " + usrFiled);
LOGGER.info("password的Field: " + pwdFiled + "\n");
//通过Class.getFields()获取所有的成员变量对象
LOGGER.info("通过Class.getFields()获取所有的成员变量对象");
Field[] fields = userClass.getFields();
for (Field field : fields) {
LOGGER.info("User的成员变量:" + field);
}
System.out.println();
//通过通过Field.getDeclaringClass获取定义这个成员变量的的Class对象
LOGGER.info("通过Field.getDeclaringClass获取定义这个成员变量的的Class对象");
Class usrClass1 = usrFiled.getDeclaringClass();
LOGGER.info("定义" + usrFiled + "成员变量的类是" + usrClass1 + "\n");
LOGGER.info(" Field信息 //");
Field信息 //
//通过Field.getModifiers()获取成员变量修饰符
LOGGER.info("通过Field.getModifiers()获取成员变量修饰符");
int modifiers = usrFiled.getModifiers();
LOGGER.info("username的修饰符:" + Modifier.toString(modifiers) + "\n");
//通过Field.getName()获取成员变量名
LOGGER.info("通过Field.getName()获取成员变量名");
String username = usrFiled.getName();
LOGGER.info("username的成员变量名:" + username + "\n");
//通过Field.getGenericType()和Field..getType()获取当前成员变量的类型和类
LOGGER.info("通过Field.getGenericType()和Field..getType()获取当前成员变量的类型和类");
Type usrFiledType = usrFiled.getGenericType();
Class usrFieldClass = usrFiled.getType();
LOGGER.info("username的类型是:" + usrFiledType);
LOGGER.info("username的类是:" + usrFieldClass + "\n");
//通过Field.toGenericString()和Field.toString()获取描述当前成员变量的字符串
LOGGER.info("通过Field.toGenericString()和Field.toString()获取描述当前成员变量的字符串");
String usrGenericString = usrFiled.toGenericString();
String usrString = usrFiled.toString();
LOGGER.info("username的字符串描述(包括通用类型):" + usrGenericString);
LOGGER.info("username的字符串描述:" + usrString + "\n");
//通过Field.equals方法判断两个Field是否相等
LOGGER.info("通过Field.equals方法判断两个Field是否相等");
LOGGER.info("usrFiled equals pwdFiled :" + usrFiled.equals(pwdFiled) + "\n");
LOGGER.info(" Field 获取注解信息 //");
Field 获取注解信息 //
//通过Field.getAnnotation(Annotation.class) 获取指定的注解
Annotation annotation = usrFiled.getAnnotation(MyAnnotationA.class);
LOGGER.info("通过Field.getAnnotation(Annotation.class) 获取指定的注解:" + annotation + "\n");
//通过Field.getDeclaredAnnotation(Annotation.class) 获取指定的注解
Annotation annotation1 = usrFiled.getDeclaredAnnotation(MyAnnotationA.class);
LOGGER.info("通过Field.getDeclaredAnnotation(Annotation.class) 获取指定的注解:" + annotation1 + "\n");
//通过Field.getAnnotationsByType(Annotation.class)获取一组指定的注解
Annotation[] annotations = usrFiled.getAnnotationsByType(MyAnnotationA.class);
for (Annotation anno : annotations){
LOGGER.info("通过Field.getAnnotationsByType(Annotation.class)获取一组指定的注解:" + anno);
}
System.out.println();
//通过Field.getDeclaredAnnotationsByType(Annotation.class)获取一组指定的注解
Annotation[] annotations1 = usrFiled.getDeclaredAnnotationsByType(MyAnnotationA.class);
for (Annotation anno : annotations1){
LOGGER.info("通过Field.getDeclaredAnnotationsByType(Annotation.class)获取一组指定的注解:" + anno);
}
System.out.println();
//通过Field.getAnnotations() 获取所有的注解
Annotation[] annotations2 = usrFiled.getAnnotations();
for (Annotation anno : annotations2) {
LOGGER.info("通过Field.getAnnotations() 获取所有的注解:" + anno);
}
System.out.println();
//通过Field.getDeclaredAnnotations() 获取所有的注解
Annotation[] annotations3 = usrFiled.getDeclaredAnnotations();
for (Annotation anno : annotations3) {
LOGGER.info("通过Field.getDeclaredAnnotations() 获取所有的注解:" + anno);
}
System.out.println();
LOGGER.info(" Field 获取某个对象的成员变量值(全部类型(基本数据类型自动装箱)) //");
Field 获取某个对象的成员变量值(全部类型(基本数据类型自动装箱)) //
//通过Field.get方法获取某个对象在此成员变量上的值
LOGGER.info("通过Field.get(Object obj)和Field.set 为当前成员变量设置和获取值[全部类型(基本数据类型自动装箱)]");
User user = new User();
LOGGER.info("user对象在username成员变量的值是:" + usrFiled.get(user).getClass() + usrFiled.get(user));
usrFiled.set(user, "张三丰");
LOGGER.info("user对象在username成员变量的值是:" + usrFiled.get(user).getClass() + usrFiled.get(user) + "\n");
LOGGER.info(" Field 获取和设置某个对象的成员变量值(基本数据类型) //");
Field 获取和设置某个对象的成员变量值(基本数据类型) //
//通过filed.setAccessible(boolean)设置字段是否可访问
LOGGER.info("通过filed.setAccessible(boolean)设置字段是否可访问");
pwdFiled.setAccessible(true);
//通过Field.getXxxx和Field.setXxxx为当前成员变量设置和获取基本数据类型的值
LOGGER.info("通过Field.getXxxx和Field.setXxxx为当前成员变量设置和获取基本数据类型的值");
LOGGER.info("成员变量类型:" + pwdFiled);
User user1 = new User("王五", 111111);
LOGGER.info("user1.password = " + pwdFiled.getInt(user1));
pwdFiled.setInt(user1, 321);
LOGGER.info("user1.password = " + pwdFiled.getInt(user1));
}
}
3.运行结果
2018-03-04 11:22:13 INFO ReflectFieldDemo:29 - Java反射-Field示例
2018-03-04 11:22:13 INFO ReflectFieldDemo:32 - 首先获取Class的对象:class pers.hanchao.reflect.common.User
2018-03-04 11:22:13 INFO ReflectFieldDemo:34 - Class对象与Field对象的相互获取 //
2018-03-04 11:22:13 INFO ReflectFieldDemo:37 - 通过Class.getDeclaredField对象获取指定的Field对象
2018-03-04 11:22:13 INFO ReflectFieldDemo:40 - username的Field: public java.lang.String pers.hanchao.reflect.common.User.username
2018-03-04 11:22:13 INFO ReflectFieldDemo:41 - password的Field: private int pers.hanchao.reflect.common.User.password
2018-03-04 11:22:13 INFO ReflectFieldDemo:44 - 通过Class.getFields()获取所有的成员变量对象
2018-03-04 11:22:13 INFO ReflectFieldDemo:47 - User的成员变量:public java.lang.String pers.hanchao.reflect.common.User.username
2018-03-04 11:22:13 INFO ReflectFieldDemo:52 - 通过Field.getDeclaringClass获取定义这个成员变量的的Class对象
2018-03-04 11:22:13 INFO ReflectFieldDemo:54 - 定义public java.lang.String pers.hanchao.reflect.common.User.username成员变量的类是class pers.hanchao.reflect.common.User
2018-03-04 11:22:13 INFO ReflectFieldDemo:56 - Field信息 //
2018-03-04 11:22:13 INFO ReflectFieldDemo:59 - 通过Field.getModifiers()获取成员变量修饰符
2018-03-04 11:22:13 INFO ReflectFieldDemo:61 - username的修饰符:public
2018-03-04 11:22:13 INFO ReflectFieldDemo:64 - 通过Field.getName()获取成员变量名
2018-03-04 11:22:13 INFO ReflectFieldDemo:66 - username的成员变量名:username
2018-03-04 11:22:13 INFO ReflectFieldDemo:69 - 通过Field.getGenericType()和Field..getType()获取当前成员变量的类型和类
2018-03-04 11:22:13 INFO ReflectFieldDemo:72 - username的类型是:class java.lang.String
2018-03-04 11:22:13 INFO ReflectFieldDemo:73 - username的类是:class java.lang.String
2018-03-04 11:22:13 INFO ReflectFieldDemo:76 - 通过Field.toGenericString()和Field.toString()获取描述当前成员变量的字符串
2018-03-04 11:22:13 INFO ReflectFieldDemo:79 - username的字符串描述(包括通用类型):public java.lang.String pers.hanchao.reflect.common.User.username
2018-03-04 11:22:13 INFO ReflectFieldDemo:80 - username的字符串描述:public java.lang.String pers.hanchao.reflect.common.User.username
2018-03-04 11:22:13 INFO ReflectFieldDemo:83 - 通过Field.equals方法判断两个Field是否相等
2018-03-04 11:22:13 INFO ReflectFieldDemo:84 - usrFiled equals pwdFiled :false
2018-03-04 11:22:13 INFO ReflectFieldDemo:86 - Field 获取注解信息 //
2018-03-04 11:22:13 INFO ReflectFieldDemo:90 - 通过Field.getAnnotation(Annotation.class) 获取指定的注解:@pers.hanchao.reflect.common.MyAnnotationA()
2018-03-04 11:22:13 INFO ReflectFieldDemo:94 - 通过Field.getDeclaredAnnotation(Annotation.class) 获取指定的注解:@pers.hanchao.reflect.common.MyAnnotationA()
2018-03-04 11:22:13 INFO ReflectFieldDemo:99 - 通过Field.getAnnotationsByType(Annotation.class)获取一组指定的注解:@pers.hanchao.reflect.common.MyAnnotationA()
2018-03-04 11:22:13 INFO ReflectFieldDemo:105 - 通过Field.getDeclaredAnnotationsByType(Annotation.class)获取一组指定的注解:@pers.hanchao.reflect.common.MyAnnotationA()
2018-03-04 11:22:13 INFO ReflectFieldDemo:111 - 通过Field.getAnnotations() 获取所有的注解:@pers.hanchao.reflect.common.MyAnnotationA()
2018-03-04 11:22:13 INFO ReflectFieldDemo:111 - 通过Field.getAnnotations() 获取所有的注解:@pers.hanchao.reflect.common.MyAnnotationB()
2018-03-04 11:22:13 INFO ReflectFieldDemo:117 - 通过Field.getDeclaredAnnotations() 获取所有的注解:@pers.hanchao.reflect.common.MyAnnotationA()
2018-03-04 11:22:13 INFO ReflectFieldDemo:117 - 通过Field.getDeclaredAnnotations() 获取所有的注解:@pers.hanchao.reflect.common.MyAnnotationB()
2018-03-04 11:22:13 INFO ReflectFieldDemo:121 - Field 获取某个对象的成员变量值(全部类型(基本数据类型自动装箱)) //
2018-03-04 11:22:13 INFO ReflectFieldDemo:124 - 通过Field.get(Object obj)和Field.set 为当前成员变量设置和获取值[全部类型(基本数据类型自动装箱)]
2018-03-04 11:22:13 INFO ReflectFieldDemo:126 - user对象在username成员变量的值是:class java.lang.String张三
2018-03-04 11:22:13 INFO ReflectFieldDemo:128 - user对象在username成员变量的值是:class java.lang.String张三丰
2018-03-04 11:22:13 INFO ReflectFieldDemo:130 - Field 获取和设置某个对象的成员变量值(基本数据类型) //
2018-03-04 11:22:13 INFO ReflectFieldDemo:133 - 通过filed.setAccessible(boolean)设置字段是否可访问
2018-03-04 11:22:13 INFO ReflectFieldDemo:136 - 通过Field.getXxxx和Field.setXxxx为当前成员变量设置和获取基本数据类型的值
2018-03-04 11:22:13 INFO ReflectFieldDemo:137 - 成员变量类型:private int pers.hanchao.reflect.common.User.password
2018-03-04 11:22:13 INFO ReflectFieldDemo:139 - user1.password = 111111
2018-03-04 11:22:13 INFO ReflectFieldDemo:141 - user1.password = 321
4.总结
通过代码实例与运行结果,总结如下:
- 要操作成员变量Field,首先应该获取Class对象
- Class对象与Field对象的相互获取
- 通过Class.getField(field_name)和Class.getDeclaredField(field_name)对象获取指定的Field对象
- 通过Class.getFields()和Class.getDeclaredFields()获取所有的成员变量对象
- 通过Field.getDeclaringClass()获取定义这个成员变量的的Class对象
- Field相关信息获取
- 通过Field.getModifiers()获取成员变量修饰符
- 通过Field.getName()获取成员变量名
- 通过Field.getGenericType()和Field.getType()获取当前成员变量的类型和类
- 通过Field.toGenericString()和Field.toString()获取描述当前成员变量的字符串
- 通过Field.equals方法判断两个Field是否相等
- Field注解信息获取
- 通过Field.getAnnotation(Annotation.class) 获取指定的注解
- 通过Field.getDeclaredAnnotation(Annotation.class) 获取指定的注解
- 通过Field.getAnnotationsByType(Annotation.class)获取一组指定的注解
- 通过Field.getDeclaredAnnotationsByType(Annotation.class)获取一组指定的注解
- 通过Field.getAnnotations() 获取所有的注解
- 通过Field.getDeclaredAnnotations() 获取所有的注解
- Field获取和设置成员变量的值
- 通过filed.setAccessible(boolean)设置字段是否可访问(尤其是对私有成员变量[private field])
- 通过Field.get和Field.set为当前成员变量设置和获取值(全部类型[基本数据类型自动装箱])
- 通过Field.getXxxx和Field.setXxxx为当前成员变量设置和获取值(只支持基本数据类型的)
备注:
- 有关获取Class对象的三种方式参见:Java反射02 : Class对象获取的三种方式和通过反射实例化对象的两种方式
- 有关getXxxx和getDeclaredXxxx参见:Java反射 : Declared的作用 ( 例如 : getMethods和getDeclaredMethods )
- 在操作Field字段是尤其注意:通过filed.setAccessible(true)设置字段可访问