您的位置:首页 > 编程语言 > Java开发

Java反射06 : 成员变量Field学习示例

2018-03-04 11:48 459 查看
超级通道: 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)设置字段可访问
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐