反射
什么是反射?反射允许对封装类的字段,方法和构造函数的信息进行编程访问。
获取class对象的三种方式
- Class.forName(“全类名”);//全类名:包名+类名
- 类名.class;//这种方式一般当作参数传递
- 对象.getClass();//当已经有了这个类的对像时使用
在Java中,万物即可为对象,如:
获取Class对象:Class
构造方法:Constructor
字段(成员变量):Field
成员方法:Method
利用反射获取构造方法
Class类中用于获取构造方法的方法
Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组
Constructor
Constructor
Constructor类中用于创建对象的方法
T newInstance(Object.. initargs):根据指定的构造方法创建对象
setAccessible(boolean flag):设置为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
31
32
33
34
35
36
37
38
39public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
protected Student(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}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
32public class Main {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//获取字节码文件
Class<?> student = Class.forName("org.example.Student");
//所有公共构造方法
Constructor<?>[] con1 = student.getConstructors();
for (int i = 0; i < con1.length; i++) {
System.out.println(con1[i]);
//public org.example.Student()
//public org.example.Student(java.lang.String,int)
}
//所有构造方法
Constructor<?>[] con2 = student.getDeclaredConstructors();
for (int i = 0; i < con2.length; i++) {
System.out.println(con2[i]);
//protected org.example.Student(int)
//public org.example.Student()
//public org.example.Student(java.lang.String,int)
}
//返回单个构造方法对象
Constructor<?> con3 = student.getDeclaredConstructor( int.class);
System.out.println(con3);
//protected org.example.Student(int)
//取消访问检查
con3.setAccessible(true);
Student std = (Student) con3.newInstance(18);
System.out.println(std);
//Student{name='null', age=18}
}
}
利用反射获取成员变量
Field[] getFields():返回所有公共成员变量对象的数组
Field[] getDeclaredFields():返回所有成员变量对象的数组
Field getField(String name):返回单个公共成员变量对象
Field getDeclaredField(String name):返回单个成员变量对象
Field类中用于创建对象的方法
void set(Object obj, Object value):赋值
Object get(Object obj)获取值。
获取成员变量示例代码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
38package org.example;
public class Student {
private String name;
private int age;
public String major;
public Student(String name, int age, String major) {
this.name = name;
this.age = age;
this.major = major;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
1 | package org.example; |
利用反射获取成员方法
Class类中用于获取成员方法的方法
Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>… parameterTypes):返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>… parameterTypes):返回单个成员方法对像
Method类中用于创建对象的方法
Object invoke(Object obj, Object… args):运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)
获取成员方法示例代码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
44package org.example;
import java.io.IOException;
public class Student {
private String name;
private int age;
public void sleep(){//公共睡觉方法
System.out.println("Student is sleeping");
}
private String eating(String food) throws IOException {//私有吃饭方法
System.out.println("Student is eating " + food);
return "奥里给";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
1 | package org.example; |
场景应用
获取对象的成员变量名和值,并写到文件中
1 | public class Student { |
1 | public class Teacher { |
1 | package org.example; |
利用反射,根据配置文件来动态的创建对象,并调用方法
在当前src目录下有pro.properties配置文件,其中内容如下
classname=org.example.xnj.Student
method=study
1 | package org.example.xnj; |
1 | package org.example.xnj; |
1 | package org.example.xnj; |
之后改变配置文件的值就能改变不同的类调用方法。