反射介绍第二弹。
Java反射(Reflection)(二)
- 获取了某个Object实例对应的Class,我们就可以通过反射获取他的一切信息。
1. 访问字段(Filed)
通过Class访问字段(Field)信息的几个方法
Field getField(String name) :获取指定名称的Field(包含父类,子类的public的Field)
Filed getDeclaredField(String name) :获取指定名称的Filed(包含子类的所有Field)
Field[] getFields() :获取所有Field(包含父类,子类的public的Field)
Filed[] getDeclaredFields() :获取所有Filed(包含子类的所有Field)
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
31
32
33
34
35
36
37package top.tobing.reflection;
import java.lang.reflect.Field;
/**
* 获取实例的字段信息
* @author Tobing
*/
public class Demo02ReflectField {
public static void main(String[] args) throws NoSuchFieldException, SecurityException {
Student stu = new Student();
// 获取Student名称为id的Field
System.out.println(stu.getClass().getField("name"));
System.out.println(stu.getClass().getField("id"));
System.out.println(stu.getClass().getDeclaredField("score"));
// 以下语句会抛出:java.lang.NoSuchFieldException 该方法不能找到父类的public方法
//System.out.println(stu.getClass().getDeclaredField("name"));
Field[] fields1 = stu.getClass().getFields(); // 获取stu的使用public修饰的方法
System.out.println("stu的public修饰Field(包含父类):");
for(Field f:fields1) {
System.out.println(f.getName());
}
Field[] fields2 = stu.getClass().getDeclaredFields();
System.out.println("本类中的所有属性(包含private):");
for(Field f:fields2) {
System.out.println(f.getName());
}
}
}
class Human{
public String name;
}
class Student extends Human {
public String id;
private double score;
}1
2
3
4
5
6
7
8
9
10# 输出结果
public java.lang.String top.tobing.reflection.Human.name
public java.lang.String top.tobing.reflection.Student.id
private double top.tobing.reflection.Student.score
stu的public修饰Field(包含父类):
id
name
本类中的所有属性(包含private):
id
score
Field的常用操作
- String getName()
返回此 Field 对象表示的字段的`名称 `
- Class<?> getType()
返回一个 Class 对象,它标识了此 Field 对象所表示字段的`声明类型`。
- int getModifiers()
以整数形式返回由此 Field 对象表示的字段的` Java 语言修饰符`。
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
29package top.tobing.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* 字段的常用方法
* @author Tobing
*/
public class Demo03ReflectField2 {
public static void main(String[] args) throws NoSuchFieldException, SecurityException {
Teacher t = new Teacher();
Field f2 = t.getClass().getDeclaredField("age");
Field f1 = t.getClass().getDeclaredField("name");
System.out.println("-----------------------------------------------------");
System.out.println("名称:"+f1.getName());
System.out.println("返回值类型:"+f1.getType());
System.out.println("Java语言修饰符int形式:"+f1.getModifiers());
System.out.println("isPrivate:"+Modifier.isPrivate(f1.getModifiers()));
System.out.println("-----------------------------------------------------");
System.out.println("名称:"+f2.getName());
System.out.println("返回值类型:"+f2.getType());
System.out.println("Java语言修饰符int形式:"+f2.getModifiers());
System.out.println("isPublic:"+Modifier.isPublic(f2.getModifiers()));
}
}
class Teacher{
private String name;
public int age;
}1
2
3
4
5
6
7
8
9
10
11# 输出结果
-----------------------------------------------------
名称:name
返回值类型:class java.lang.String
Java语言修饰符int形式:2
isPrivate:true
-----------------------------------------------------
名称:age
返回值类型:int
Java语言修饰符int形式:1
isPublic:true- String getName()
2. 访问字段的值
Object get(Object obj) :返回指定实例对应字段的值
Returns the value of the field represented by this Field, on the specified object.
void setAccessible(boolean flag) :设置是否可以范围(权限不够的时候)
Set the accessible flag for this object to the indicated boolean value.
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
30package top.tobing.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* 字段的常用方法
* @author Tobing
*/
public class Demo03ReflectField3 {
public static void main(String[] args) throws Exception{
People p = new People();
p.setName("张三丰");
Field f1 = p.getClass().getDeclaredField("name");
// f1.get(p); //直接执行该语句会抛出异常java.lang.IllegalAccessException
// cannot access a member of class top.tobing.reflection.People with modifiers "private"
//不能访问修饰符为private的字段
// 暴力反射,忽略修饰符 // 通常情况下,如果修饰符权限不够就考虑使用该方法(反射是非常规的用法)
f1.setAccessible(true);
Object obj = f1.get(p);
System.out.println(obj); // 输出: 张三丰
f1.set(p,"张无忌");
System.out.println(f1.get(p)); // 修改后输出 张无忌
}
}
class People{
private String name;
public int age;
public void setName(String name) {
this.name = name;
}
}
总结
- 理解还未深入,仍需学习。