0%

Java 反射

如果有问题,希望指出

Reflection(反射)是 Java 被视为动态语言的关键,反射机制允许程序在执行期借用 Reflection API 获取任何内部信息,并能操作任何对象的内部属性级方法。

Java 反射机制主要提供一下功能:

  • 在运行时构造任意一个类的对象
  • 在运行时获取任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的方法
  • 生成动态代理

Java 反射提供三种获取 Class 对象的方法:

1
2
3
4
5
6
7
8
Person person = new Person(1L, "反射");
//1、通过对象名
Class personClass = person.getClass();
//2、通过类名
Class baseClass = Person.class;
//3、通过全类名
Class baseClass2 = Class.forName("com.example.basejava.basics.reflect.Person");

Class 是一个类,一个描述类的类。它封装了描述方法的 Method,描述字段的 Filed,描述构造器的 Constructor 等属性。

代码

Person 类

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class Person implements Serializable {

private Long id;
private String name;

static {
System.out.println("测试反射静态代码块");
}

Person(Person person) {
System.out.println("(默认)反射测试类构造了" + person);
}

public Person() {
System.out.println("调用了公有、无参构造方法执行了。。。");
}

Person(Long id, String name) {
this.id = id;
this.name = name;
}

Person(String name) {
this.name = name;
System.out.println("name+" + name);
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

反射具体代码:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
public class ReflectTest {

public static void main(String[] args) throws ClassNotFoundException,
IntrospectionException,
IllegalAccessException,
InvocationTargetException,
InstantiationException,
NoSuchMethodException {
Person person = new Person(1L, "反射");
//1、通过对象名
Class clazz1 = person.getClass();
//2、通过类名
Class clazz = Person.class;
//3、通过全类名
Class clazz2 = Class.forName("com.example.basejava.basics.reflect.Person");

System.out.println("----获取文件名----");
System.out.println(clazz.getName());

System.out.println("---获取类内部信息-----");
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
//获取内部成员变量,比如 id、name
String key = field.getName();
PropertyDescriptor descriptor = new PropertyDescriptor(key, clazz);
Method method = descriptor.getReadMethod();
Object value = method.invoke(person);
System.out.println(key + ":" + value);
}

System.out.println("----获取实例对象----");
//利用Class对象的newInstance方法创建一个类的实例
Object obj = clazz.newInstance();
System.out.println(obj);

System.out.println("------获取方法---------");
//获取方法,不能获取private方法,且获取从父类继承来的所有方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.print(" " + method.getName());
}
System.out.println();

//获取所有方法,包括私有方法
methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(" " + method.getName());
}
System.out.println();

//获取指定方法
Method method = clazz.getDeclaredMethod("setName", String.class);
System.out.println(method);

//修改类内部信息,setName("反射)
method.invoke(obj, "反射");
System.out.println(obj);

System.out.println("----所有公有构造方法-----");
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}

System.out.println("-----所有的构造方法(包括:私有、受保护、默认、公有)-------");
constructors = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}

System.out.println("--------获取公有、无参的构造方法--------");
Constructor constructor = clazz.getConstructor(null);
System.out.println("constructor : " + constructor);

System.out.println("------获取私有构造方法,并调用-------");
Object object = constructor.newInstance();
constructor = clazz.getDeclaredConstructor(String.class);
System.out.println(constructor);
//调用构造方法
constructor.setAccessible(true);
object = constructor.newInstance("男");
System.out.println(object);
}
}

输出:

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
测试反射静态代码块
----获取文件名----
com.example.basejava.basics.reflect.Person
---获取类内部信息-----
id:1
name:反射
----获取实例对象----
调用了公有、无参构造方法执行了。。。
Person{id=null, name='null'}
------获取方法---------
toString getName setName getId setId wait wait wait equals hashCode getClass notify notifyAll
toString
getName
setName
getId
setId

public void com.example.basejava.basics.reflect.Person.setName(java.lang.String)
Person{id=null, name='反射'}
----所有公有构造方法-----
public com.example.basejava.basics.reflect.Person()
-----所有的构造方法(包括:私有、受保护、默认、公有)-------
com.example.basejava.basics.reflect.Person(java.lang.String)
com.example.basejava.basics.reflect.Person(java.lang.Long,java.lang.String)
public com.example.basejava.basics.reflect.Person()
com.example.basejava.basics.reflect.Person(com.example.basejava.basics.reflect.Person)
--------获取公有、无参的构造方法--------
constructor : public com.example.basejava.basics.reflect.Person()
------获取私有构造方法,并调用-------
调用了公有、无参构造方法执行了。。。
com.example.basejava.basics.reflect.Person(java.lang.String)
name+男
Person{id=null, name='男'}

客官,赏一杯coffee嘛~~~~