Java 的反射

#Java 反射
Java 反射是在 java.lang.reflect 包类,包含 Constructor、Method、Field 的反射。

涉及的方法 说明
创建类 Constructor Class.getConstructor( ) Constructor.newInstance(args) newInstance( ) 方法可以为无参调用
方法 Method Class.getMethods( ) Class.getDeclaredMethods( ) getMethods( ) 返回自身和父类的方法; getDeclaredMethods( ) 只返回自身的方法
变量 Field Class.getFields( ) Class.getDeclaredFields( ) getFields() 获取这个类和它父类的 public 成员变量; getDeclaredFields() 获取这个类和它父类的全部成员变量

1. 通过反射创建类 Constructor

无参构造

1
2
3
Class clazz = Class.forName("类的路径");
Constructor constructor = cl.getConstructor();
Object object = constructor.newInstance();

有参构造

1
2
3
4
Class classType = Class.forName(classPath);
Constructor constructor = classType.getConstructor(intArgsClass);
constructor.setAccessible(true); // 压制 java 检查,防止当构造函数时 private 时拿不到
Object object = constructor.newInstance(intArgs);

说明

  • getConstructor(Class[])Class[] 是构造函数参数类型

例如 Employee(String name, long salary), 则 Class[] 就是 new Class[]{String.class, long.class}

  • onstructor.newInstance(Object[]) Object[] 是构造函数的具体参数值

例如 Employee(String name, long salary) 则 Object[] 就是 new Object[]{“张三”, 5000}

  • 如果是无参构造函数使用 Class.newInstance( ) 即可,可不用反射

例子

调用了无参构造函数
1
2
3
4
5
6
7
8
9
10
11
private Object createEmployeeByClassPath(String classPath){
try {
Class cl = Class.forName(classPath);
Constructor constructor = cl.getConstructor();
Object object = constructor.newInstance();
return object;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
如果是 private 的构造函数
1
2
3
4
5
// 获取 private 的构造函数
Class cl = Class.forName(classPath);
Constructor constructor = cl.getDeclaredConstructor();
constructor.setAccessible(true);
Object object = constructor.newInstance();
调用有参构造函数
1
2
3
4
5
6
7
8
9
10
private void createEmployeeByConstructor(String classPath, Class[] intArgsClass, Object[] intArgs){
try {
Class classType = Class.forName(classPath);
Constructor constructor = classType.getConstructor(intArgsClass);
constructor.setAccessible(true); // 压制 java 检查,防止当构造函数时 private 时拿不到
Object object = constructor.newInstance(intArgs);
} catch (Exception e) {
e.printStackTrace();
}
}

2.通过反射调用方法 Method

获取方法

1
2
Class.getMethods() 返回自身和父类的方法
Class.getDeclaredMethods() 只返回自身的方法

获取指定的方法

1
2
// methodName 是方法名,intArgsClass 是方法签名参数类型
Method method = clazz.getDeclaredMethod(methodName, intArgsClass);

调用方法

1
method.invoke(Object, intArgs) // intArgs 是具体的参数类型

例子

获取方法
1
2
3
4
5
6
7
8
9
10
11
12
13
private void getMethods(Object object){
// 获取所有方法,包括父类的
Method[] methods = object.getClass().getMethods();
for (Method method : methods){
Log.i(TAG, "getMethods method " + method.toString());
}

// 至获取自身定义的方法
Method[] methods1 = object.getClass().getDeclaredMethods();
for (Method method : methods1){
Log.i(TAG, "getMethods method " + method.toString());
}
}
调用方法
1
2
3
4
5
6
7
8
9
10
11
// 反射调用方法
private void invokeMethod(Object object, String methodName, Class[] intArgsClass, Object[] intArgs){
try {
Class clazz = object.getClass();
Method method = clazz.getDeclaredMethod(methodName, intArgsClass);
method.setAccessible(true);
Object returnValue = method.invoke(object, intArgs);
} catch (Exception e) {
e.printStackTrace();
}
}

3. 通过反射获取成员变量 Field

获取 Field

1
2
Fields[] fields = Class.getFields()  // 获取这个类和它父类的 public 成员变量
Fields[] fields = Class.getDeclaredFields() //获取这个类和它父类的全部成员变量

设置成员变量的值

1
2
3
Class.getDeclaredField(fieldName) // 获取具体的成员变量
Field.setAccessible(true);
Field.set(object, value) // 设值

例子

获取成员变量
1
2
3
4
5
6
7
8
// 获取成员变量
private void getFields(Object object){
Field[] fields = object.getClass().getFields();
for (Field field : fields){
Class type = field.getType();
String name = field.getName();
}
}
获取具体的成员变量
1
2
3
4
5
6
7
8
9
10
private void getField(Object object, String fieldName){
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object fieldVale = field.get(object);
String name = (String) fieldVale;
} catch (Exception e) {
e.printStackTrace();
}
}
设置成员变量的值
1
2
3
4
5
6
7
8
9
private void setFieldValue(Object object, String fieldName, Object value){
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
} catch (Exception e){
e.printStackTrace();
}
}

4. 获取注解

Metho, Field, Constructor 都可以直接调用getAnnotationgetAnnotation(Class<> annotationType) 获取

使用注解的开源库都会用到 EeventBus, ARouter 等

1
2
3
4
5
6
7
8
9
private void getAnnotationMethod(Object object){
Method[] methods = object.getClass().getDeclaredMethods();
for (Method method: methods){
MyAnnotation annoType = method.getAnnotation(MyAnnotation.class);
if (annoType != null){
Log.i(TAG, "getAnnotationMethod name = " + method.getName());
}
}
}

5.获取修饰符

Metho, Field, Constructor 都可以直接调用 getModifier() 获取
Modifier 这个类可以分析这个返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
private void getModifiers(Object object){
Field[] fields1 = object.getClass().getDeclaredFields();
for (Field field : fields1){
Class type = field.getType();
String name = field.getName();
printModifier(name, field.getModifiers());
}
}

private void printModifier(String name, int modifier){
String modifiers = Modifier.toString(modifier);
boolean isFinal = Modifier.isFinal(modifier);
}

6. 其他

setAccessible(true)

Metho, Field, Constructor 都可以设置 setAccessible(true), 压制 java 检查,防止 private 时拿不到

getConstructor 与 getDeclaredConstructor 的区别

  • getDeclaredConstructor 可以返回 private 的构造函数,但是需要 Constructor.setAccessible(true), 配合一起使用
1
2
3
4
Class cl = Class.forName(classPath);
Constructor constructor = cl.getDeclaredConstructor();
constructor.setAccessible(true);
Object object = constructor.newInstance();
  • getConstructor 只是返回 public 的构造函数
1
2
3
Class cl = Class.forName(classPath);
Constructor constructor = cl.getConstructor();
Object object = constructor.newInstance();

7.完整的示例代码

ReflectActivity.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
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/**
* 反射的
*/
public class ReflectActivity extends Activity {
private static final String TAG = "ReflectActivity";

private static final String CLASS_PATH = "com.yxhuang.myapplication.reflect.Employee";

private Employee mEmployee;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reflect);

// createEmployeeByConstructor(CLASS_PATH, new Class[]{String.class, long.class}, new Object[]{"张三", 5000});


// Object object = createEmployeeByClassPath(CLASS_PATH);
// getMethods(object);

// invokeMethod(object, "setName", new Class[]{String.class}, new Object[]{"李四"});

// mEmployee = new Employee("李四", 5000, 22);
// mEmployee.setAddress("广东");
// getFields(mEmployee);
// getField(mEmployee, "mName");
// setFieldValue(mEmployee, "mName", "张三");

// getAnnotationMethod(mEmployee);

classInstance();

}

// 调用了无参构造函数
private Object createEmployeeByClassPath(String classPath){
try {
Class cl = Class.forName(classPath);
Constructor constructor = cl.getConstructor();
Object object = constructor.newInstance();
Employee employee = (Employee) object;
Log.i(TAG, "createEmployeeByClassPath " + employee.toString());
return object;
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Error" + e.getMessage());
}
return null;

// 获取 private 的构造函数
// Class cl = Class.forName(classPath);
// Constructor constructor = cl.getDeclaredConstructor();
// constructor.setAccessible(true);
// Object object = constructor.newInstance();
}

// 调用有参构造函数
private void createEmployeeByConstructor(String classPath, Class[] intArgsClass, Object[] intArgs){
try {
Class classType = Class.forName(classPath);
Constructor constructor = classType.getConstructor(intArgsClass);
constructor.setAccessible(true); // 压制 java 检查,防止当构造函数时 private 时拿不到
Object object = constructor.newInstance(intArgs);
Employee employee = (Employee) object;

Log.i(TAG, "createEmployeeByConstructor " + employee.toString());
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "createEmployeeByConstructor error " + e.getMessage());
}
}

private void getMethods(Object object){
// 获取所有方法,包括父类的
Method[] methods = object.getClass().getMethods();
for (Method method : methods){
Log.i(TAG, "getMethods method " + method.toString());
}

Log.i(TAG, " ----------------------------------------");
// 至获取自身定义的方法
Method[] methods1 = object.getClass().getDeclaredMethods();
for (Method method : methods1){
Log.i(TAG, "getMethods method " + method.toString());
}

}

// 反射调用方法
private void invokeMethod(Object object, String methodName, Class[] intArgsClass, Object[] intArgs){
try {
Class clazz = object.getClass();
Method method = clazz.getDeclaredMethod(methodName, intArgsClass);
method.setAccessible(true);
Object returnValue = method.invoke(object, intArgs);
Log.i(TAG, "invokeMethod returnValue ");
print(object);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "invokeMethod error " + e.getMessage());
}
}

// 获取成员变量
private void getFields(Object object){
Field[] fields = object.getClass().getFields();
for (Field field : fields){
Class type = field.getType();
String name = field.getName();
Log.i(TAG, " getFields type= " + type + " name= " + name);
}

Log.i(TAG, " ----------------------------------------");

// 获取方法的标识符
Field[] fields1 = object.getClass().getDeclaredFields();
for (Field field : fields1){
Class type = field.getType();
String name = field.getName();
Log.i(TAG, " getFields type= " + type + " name= " + name);
printModifier(name, field.getModifiers());
}
}

// 获取具体的成员变量
private void getField(Object object, String fieldName){
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object fieldVale = field.get(object);
String name = (String) fieldVale;
Log.i(TAG, " getField name= " + name);
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, " getField error= " + e.getMessage());
}
}

// 设置成员变量的值
private void setFieldValue(Object object, String fieldName, Object value){
Log.i(TAG, "before set field ");
print(object);
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

Log.i(TAG, "after set field ---- ");
print(object);
} catch (Exception e){
e.printStackTrace();
Log.i(TAG, " getField error= " + e.getMessage());
}
}

// 获取注解的
private void getAnnotationMethod(Object object){
Method[] methods = object.getClass().getDeclaredMethods();
for (Method method: methods){
MyAnnotation annoType = method.getAnnotation(MyAnnotation.class);
if (annoType != null){
Log.i(TAG, "getAnnotationMethod name = " + method.getName());
}
}
}


private void print(Object object){
Employee employee = (Employee) object;
Log.i(TAG, "print " + employee.toString());
}

private void printModifier(String name, int modifier){
String modifiers = Modifier.toString(modifier);

boolean isFinal = Modifier.isFinal(modifier);
Log.i(TAG, "name = " + name + " modifier= " + modifiers + " isFinal= " + isFinal);
}

// 不是用反射
private void classInstance(){
try {
Employee employee = Employee.class.newInstance();
Log.i(TAG, "classInstance " + employee.toString());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

}
}

Employee.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
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
/**
* Created by yxhuang
* Date: 2018/11/10
* Description:
*/
public class Employee extends Person {
private static final String TAG = "Employee";

private String mName;
private long mSalary;

public String mAddress;


public Employee(){
super(20);
Log.i(TAG, "调用 Employee 无参构造函数");
}

public Employee(String name, long salary, int age) {
super(age);
mName = name;
mSalary = salary;
Log.i(TAG, "调用 Employee 有参参构造函数 name= " + name + " salary= " + salary);
}


public String getName() {
return mName;
}

@MyAnnotation
public void setName(String name) {
Log.i(TAG, "set name " + name);
mName = name;
}

public long getSalary() {
return mSalary;
}

@MyAnnotation
public void setSalary(long salary) {
mSalary = salary;
}

public String getAddress() {
return mAddress;
}

public void setAddress(String address) {
mAddress = address;
}

@Override
public String toString() {
return "Employee{" +
"mName='" + mName + '\'' +
", mSalary=" + mSalary +
", mAag=" + mAag +
'}';
}
}

Person.java

1
2
3
4
5
6
public class Person {
public int mAag;
public Person(int aag) {
mAag = aag;
}
}

MyAnnotation.java

1
2
3
4
5
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MyAnnotation {

}
yxhuang wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客