Java高级-反射
反射(Reflect)
概念及作用
概念:反射(Reflect)是在运行时动态访问类与对象的技术。
反射是JDK1.2版本后的高级特性,属于java.lang.reflect包下。
大多数Java框架都基于反射实现参数配置、动态注入等特性。
用于不修改源代码(静态编译)的情况,程序运行时动态创建对应的方法。
反射机制根据外部输入的类名找到对应的类中的实现方法,实现动态功能,后续添加其他方法类也不需要修改源代码。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15Scanner sc = new Scanner(System.in);
System.out.println("请输入计算方法:");
String op = sc.next();
System.out.println("请输入第一个数据:");
Float a = sc.nextFloat();
System.out.println("请输入第二个数据:");
Float b = sc.nextFloat();
try{
// 反射技术动态创建实现类并进行计算,动态访问类
MathOpetation mathOpetation = (MathOpetation) Class.forName("com.codewhale.reflect." + op).newInstance();
float result = mathOpetation.mathOperation(a, b);
System.out.println("结果:"+result);
}catch (Exception e){
e.printStackTrace();
}核心类
Class类
Class是JVM中代表“类和接口”的类。
Class对象具体包含了某个特定类的结构信息。
通过Class对象可获取对应类的构造方法/方法/成员变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17try {
// Class.forName方法将指定的类加载到jvm,并返回对应class对象
Class studentClass = Class.forName("com.codewhale.reflect.Student");
System.out.println("studentClass已被加载到JVM中");
// newInstance通过默认无参构造方法创建新的对象
Student student = (Student)studentClass.newInstance();
System.out.println(student);
} catch (ClassNotFoundException e) {
// 类名与类路径书写错误是抛出"类无法找到"异常
e.printStackTrace();
} catch (InstantiationException e) {
// 非法访问异常,当在作用域外访问对象方法或成员变量时抛出
e.printStackTrace();
} catch (IllegalAccessException e) {
// 对象无法被实例化时抛出
e.printStackTrace();
}Constructor构造方法类
Method方法类
Method对象指代某个类中的方法描述。
Method对象使用classObj.getMethod()方法获取。
通过Method对象调用指定对象的对应方法。

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
26try {
Class studentClass = Class.forName("com.codewhale.reflect.Student");
Constructor constructor = studentClass.getConstructor(new Class[]{
Integer.class, String.class, Integer.class
});
Student student = (Student)constructor.newInstance(new Object[]{
1, "张三", 22
});
Method studentUpdateAge = studentClass.getMethod("updateStudent", new Class[]{
Integer.class
});
Student student1 = (Student) studentUpdateAge.invoke(student, new Object[]{
30
});
System.out.println(student1);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
e.printStackTrace();
}Field成员变量类
Field对应某个具体类中的成员变量的声明。
Field对象使用classObj.getField()方法获取。
通过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
27try {
Class studentClass = Class.forName("com.codewhale.reflect.Student");
Constructor studentConstructor = studentClass.getConstructor(new Class[]{
Integer.class, String.class, Integer.class
});
Student student = (Student)studentConstructor.newInstance(new Object[]{
1,"张三",25
});
Field studentName = studentClass.getField("name");
System.out.println("原姓名:"+studentName.get(student).toString());
studentName.set(student, "张一");
String studentName1 = (String)studentName.get(student);
System.out.println("更改后的姓名:"+studentName1);
System.out.println(student);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}getDeclared系列方法说明
getDeclaredConstructor(s)|Method(s)|Field(s)获取对应对象,加s代表获取所有对象。
getConstructor(s)|Method(s)|Field(s)只能获取public对象。
访问非作用域内构造方法、方法、成员变量,会抛出异常。
getDeclared系列方法可获取private等对象。
- Field类中getModifiers()方法用于判断该成员变量是否为public变量。当结果为1则为public修饰;当结果为2则为private修饰
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
31try {
Class studentClass = Class.forName("com.codewhale.reflect.Student");
Constructor studentConstructor = studentClass.getConstructor(new Class[]{
Integer.class, String.class, Integer.class
});
Student student = (Student)studentConstructor.newInstance(new Object[]{
1,"张三",25
});
Field[] declaredFields = studentClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
if (declaredField.getModifiers() == 1){ // 结果为1则为public修饰
Object val = declaredField.get(student);
System.out.println(declaredField.getName()+":"+val);
}else if (declaredField.getModifiers() == 2){ // 结果为2则为private修饰,则需要使用getXxx()调用。
String methodName = "get"+declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1);
Method method = studentClass.getMethod(methodName);
Object yet = method.invoke(student);
System.out.println(declaredField.getName()+":" + yet);
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 CodeWhale-Blog!
评论





