概述
Field是一个类,位于Java.lang.reflect包下,在Java反射中Field用于获取某个类的属性或该属性的属性值。
获取Field类对象
下面的四种获取Field类都将使用下面这个实体类
1
2
3
4
5
6
7
8//Person.java public class Person{ public String name; private Integer age; private String sex; //省略所有属性的set、get方法 }
Class.getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段(包括私有成员)
1
2
3
4
5
6
7
8
9
10
11//通过Class.getDeclaredField(String name)获取类或接口的指定已声明字段。 Field f1 = person.getClass().getDeclaredField("name"); System.out.println("-----Class.getDeclaredField(String name)用法-------"); System.out.println(f1); /* -----Class.getDeclaredField(String name)用法------- public java.lang.String com.mao.test.Person.name */
Class.getDeclaredFields()
返回 Field 对象的一个数组,该数组包含此 Class 对象所表示的类或接口所声明的所有字段(包括私有成员)
1
2
3
4
5
6
7
8
9
10
11
12//通过Class.getDeclaredFields()获取类或接口的指定已声明字段。 Field[] f2 = person.getClass().getDeclaredFields(); for(Field field:f2) { System.out.println(field); } /* 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)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
1
2
3
4
5
6
7
8//通过Class.getField(String name)返回一个类或接口的指定公共成员字段,私有成员报错。 Field f3=person.getClass().getField("name"); System.out.println(f3); /* public java.lang.String com.mao.test.Person.name */
Class.getFields()
返回一个包含某些 Field 对象的数组,该数组包含此 Class 对象所表示的类或接口的所有可访问公共字段。
1
2
3
4
5
6
7
8
9
10
11
12//通过Class.getField(),返回 Class 对象所表示的类或接口的所有可访问公共字段。 Field []f4 = person.getClass().getFields(); for(Field fields:f4) { //因为只有name属性为共有,因此只能遍历出name属性 System.out.println(fields); } /* public java.lang.String com.mao.test.Person.name */
Field的主要方法
Field类中最常用的是get(Object obj)和set(Object obj, Object value)这两个方法,所以这两个方法是最重要的
getType(): 获取属性声明时类型对象(返回class对象)
getGenericType() : 返回属性声的Type类型
getName() : 获取属性声明时名字
getAnnotations() : 获得这个属性上所有的注释
getModifiers() : 获取属性的修饰
isEnumConstant() : 判断这个属性是否是枚举类
isSynthetic() : 判断这个属性是否是 复合类
get(Object obj) : 取得obj对象这个Field上的值
set(Object obj, Object value) : 向obj对象的这个Field设置新值value
下面便将比较重要的给代码演示了,其他的便不演示了
getType()
获取属性声明时类型对象(返回class对象)
Java Field.getType()获取属性声明时类型对象,它标识了此Field对象所表示字段的声明类型。
getType()返回的是Class对象,如果属性是一个泛型,从getType()只能得到这个属性的接口类型。
具体的代码可以看getGenericType()中的使用,在这里将getGenericType和getType()对比学习
getGenericType()
getType(): 获取属性声明时类型对象(返回class对象)
getGenericType() : 返回属性声明时的Type类型
getType() 和 getGenericType()的区别 :
-
首先是
返回的类型不一样
,一个是Class对象一个是Type接口。 -
如果属性是一个泛型,从getType()只能得到这个属性的接口类型。但从getGenericType()还能得到这个泛型的参数类型。
-
getGenericType()如果当前属性有签名属性类型就返回,否则就返回 Field.getType()。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24public class FieldSpy<T>{ public boolean[][] b = {{true, true}, {false, false}}; public String name = "test"; public Integer integer = 23; public T type; public static final String CLASS_NAME = "com.abc.test.Test"; public static void main(String[] args) { try { // 返回的是一个类 Class<?> aClass = Class.forName(CLASS_NAME); Field[] fields = aClass.getFields(); for (Field field : fields) { System.out.println("Field:" + field.getName()); System.out.println("Type:n " + field.getType().getCanonicalName()); System.out.println("GenericType:n " + field.getGenericType().toString()); System.out.println("n"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30Field:b //二维的布尔值数组 Type: boolean[][] GenericType: class [[Z Field:name Type: java.lang.String GenericType: class java.lang.String Field:integer Type: java.lang.Integer GenericType: class java.lang.Integer Field:type //泛型 T 类型,运行时被擦除为 Object Type: java.lang.Object GenericType: T Field:CLASS_NAME Type: java.lang.String GenericType: class java.lang.String
getName()
获取属性声明时名字
1
2
3
4
5
6
7
8
9
10
11
12
13class A { int fild = 3; //这个是staticFild的注解 static int staticFild = 4; } public class Test { public static void main(String[] args) throws NoSuchFieldException { Field field = A.class.getDeclaredField("fild"); String name = field.getName(); System.out.println(name);//fild } }
getAnnotations()
获得这个属性上所有的注释
1
2
3
getModifiers()
获取属性的修饰
1
2
3
isEnumConstant()
判断这个属性是否是枚举类
1
2
3
isSynthetic()
判断这个属性是否是 复合类
1
2
3
get(Object obj)
取得obj对象这个Field上的值
-
如果字段不是静态字段的话,要传入反射类的对象.如果传null是会报java.lang.NullPointerException
-
如果字段是静态字段的话,传入任何对象都是可以的,包括null
获取属性的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class Test { public static String num1 = "abc"; public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException { //使用反射第一步:获取操作类FieldDemo所对应的Class对象 Class <?>cls = Class.forName("com.abc.test.Test"); //使用FieldDemo类的class对象生成 实例 Object obj = cls.newInstance(); //通过Class类中getField(String name): 获取类特定的方法,name参数指定了属性的名称 Field field = cls.getField("num1"); //拿到了Field类的实例后就可以调用其中的方法了 //方法:get(Object obj) 返回指定对象obj上此 Field 表示的字段的值 System.out.println("属性值: " + field.get(obj)); //方法: set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值 field.set(obj, "新值"); System.out.println("修改属性值后 --> get(Object obj): " + field.get(obj)); } }
运行结果:
1
2
3属性值: abc 修改属性值后 --> get(Object obj): 新值
get()传值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class A { int fild = 3; static int staticFild = 4; } public class Test { public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException { Field field = A.class.getDeclaredField("fild"); int a= (Integer)field.get(new A()) ; // int c= (Integer)field.get(null) ; //不是静态字段不能传null System.out.println(a); Field staticfield = A.class.getDeclaredField("staticFild"); int b = (Integer)staticfield.get("") ; int d = (Integer)staticfield.get(null) ; System.out.println(b); System.out.println(d); } }
运行结果
1
2
3
43 4 4
set(Object obj, Object value)
向obj对象的这个Field设置新值value
将指定对象变量上此 Field 对象表示的字段设置为指定的新值.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class Test { public static String num1 = "abc"; public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException { //使用反射第一步:获取操作类FieldDemo所对应的Class对象 Class <?>cls = Class.forName("com.abc.test.Test"); //使用FieldDemo类的class对象生成 实例 Object obj = cls.newInstance(); //通过Class类中getField(String name): 获取类特定的方法,name参数指定了属性的名称 Field field = cls.getField("num1"); //拿到了Field类的实例后就可以调用其中的方法了 //方法:get(Object obj) 返回指定对象obj上此 Field 表示的字段的值 System.out.println("属性值: " + field.get(obj)); //方法: set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值 field.set(obj, "新值"); System.out.println("修改属性值后 --> get(Object obj): " + field.get(obj)); } }
运行结果:
1
2
3属性值: abc 修改属性值后 --> get(Object obj): 新值
通过set(Object obj,value)重新设置新的属性值,并且当我们需要获取私有属性的属性值得时候,我们必须设置Accessible为true,然后才能获取
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31public 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)); } }
运行结果:
1
2
3
4
5
6
7
8
9
10
11-----Class.getDeclaredField(String name)用法------- VipMao -----遍历属性值------- VipMao 24 男 ----修改name属性后再遍历属性值------ Maoge 24 男
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
最后
以上就是雪白银耳汤最近收集整理的关于Field的使用概述获取Field类对象Field的主要方法的全部内容,更多相关Field内容请搜索靠谱客的其他文章。
发表评论 取消回复