Jinlong's Blog

笔记:Java中的反射机制

定义

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。 —-摘自某百科

实现

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package MyTest;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.io.Serializable;
class Human implements Serializable {
private int age = 0;
private String name = "";
public Human() {
}
public Human(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String []args) {
Human human = new Human();
//获取class对象,方式一
System.out.println("###获取class对象,方式一###");
Class<Human> c1 = Human.class;
System.out.println(c1);
//方式二
System.out.println("###方式二###");
Class<? extends Human> c2 = human.getClass();
System.out.println(c2);
//方式三
System.out.println("###方式三###");
Class<?> c3 = null;
try {
c3 = Class.forName("MyTest.Human");
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(c3);
//生成对象
System.out.println("###生成对象###");
Human h3 = null;
try {
h3 = (Human)c3.newInstance();
} catch(InstantiationException e) {
e.printStackTrace();
} catch(IllegalAccessException e) {
e.printStackTrace();
}
h3.setName("lijinlong");
System.out.println(h3.getName());
//获取构造函数
System.out.println("###获取构造函数###");
Constructor<?> con3 = null;
try {
con3 = c3.getConstructor(String.class, int.class);
}
catch(NoSuchMethodException e) {
e.printStackTrace();
}
try {
h3 = (Human)con3.newInstance("zhouyi", 19);
} catch(InstantiationException e) {
e.printStackTrace();
} catch(IllegalAccessException e) {
e.printStackTrace();
} catch(InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(h3.getName());
//取得类的构造方法
System.out.println("###获取类的构造方法###");
Constructor<?>[] cons = c3.getConstructors();
System.out.println(Arrays.toString(cons));
//取得接口
System.out.println("###取得接口###");
Class<?>[] interfaces = c3.getInterfaces();
System.out.println(Arrays.toString(interfaces));
//取得父类(Java中不允许多继承,所以只有一个)
System.out.println("###取得父类###");
Class<?> superClass = c3.getSuperclass();
System.out.println(superClass);
//取得类的所有方法
System.out.println("###取得类的所有方法###");
Method []methods = c3.getMethods();
System.out.println(Arrays.toString(methods));
//调用获取的方法
System.out.println("###调用获取的方法###");
Method method = null;
try {
method = c3.getMethod("setName", String.class);
} catch(NoSuchMethodException e) {
e.printStackTrace();
}
try {
method.invoke(h3, "seer");
} catch(IllegalAccessException e) {
e.printStackTrace();
} catch(InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(h3.getName());
//获取类的属性,并改变属性值
System.out.println("###获取类的属性,并改变属性值###");
h3.setName("rongjie");
Field nameField = null;
try {
//也可以用getField,但是getField不可以获取私有变量
nameField = c3.getDeclaredField("name");
} catch(NoSuchFieldException e) {
e.printStackTrace();
}
nameField.setAccessible(true);
String name = null;
try {
nameField.set(h3, "gear");
name = (String)nameField.get(h3);
} catch(IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(name);
}
}

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
###获取class对象,方式一###
class MyTest.Human
###方式二###
class MyTest.Human
###方式三###
class MyTest.Human
###生成对象###
lijinlong
###获取构造函数###
zhouyi
###获取类的构造方法###
[public MyTest.Human(), public MyTest.Human(java.lang.String,int)]
###取得接口###
[interface java.io.Serializable]
###取得父类###
class java.lang.Object
###取得类的所有方法###
[public java.lang.String MyTest.Human.getName(), public void MyTest.Human.setName(java.lang.String), public void MyTest.Human.setAge(int), public int MyTest.Human.getAge(), public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
###调用获取的方法###
seer
###获取类的属性,并改变属性值###
gear

```