反射介绍
可以不直接new 对象,或调用方法。
用另一种创建某个对象(字符串的方式),或调用某个对象的方法(字符串的方式)。
反射这种间接调用效率肯定是不如直接调用的。
程序不知道具体要创建接口的哪个实现类,
在启动时,通过读取配置文件才知道要创建那个实现类。
先学习语法,然后可以通过结合动态代理加深理解。
反射的场景
一般的开发很少直接用到,不过在各类框架中基本离不开。
另外如果要自研框架,或者对框架定制功能,通常也会用到。
- spring以xml配置去注册bean
- 动态代理以及其衍生的各类服务
- 远程调用
- 日志,监控
- 缓存
- 权限
- spring-事务注解
- 使用注解的实现的各种功能
- 软件破解。。。等等
语法示例
普通的bean
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
|
package com.test.base_java;
public class Person {
private String name;
Integer age;
public Person() {
}
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.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
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
|
package com.test.base_java;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Reflect1 {
public static void main(String[] ss) throws Exception {
// 1. 获取class对象
Person p1 = new Person();
Class class1 = p1.getClass();
System.out.println("obj.getClass " + class1.getName());
String Pname = "com.test.base_java.Person";
Class class2 = Class.forName(Pname);
System.out.println("forName " + class2.getName());
// 2. 创建对象
Person p2 = (Person) class1.newInstance();
p2.setName("zs111");
System.out.println("2. 创建对象");
System.out.println(p2);
// 3. 获取构造器
Constructor[] constructors = class1.getConstructors();
System.out.println("3. 类的构造器为");
for (Constructor cst : constructors) {
System.out.println(cst);
}
// 4. 有参数构造对象
System.out.println("4. 通过有参构造对象");
Constructor cst2 = class1.getConstructor(String.class, Integer.class);
Person p3 = (Person) cst2.newInstance("zs222", 5);
System.out.println(p3.getName());
// 5. 打印类的方法
System.out.println("5. 该类包含的方法");
Method[] methods = class1.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
// 6. 调用 getName方法
System.out.println("6. 反射调用方法 ");
String attr = "name";
String methodName1 = "get" + initcap(attr);
String methodName2 = "set" + initcap(attr);
Method getName = class1.getMethod(methodName1);
Method setName = class1.getMethod(methodName2, String.class);
setName.invoke(p1, "zs_p111");
System.out.println(getName.invoke(p1));
// 设置属性 直接操作对象p1的name
System.out.println("7. 直接操作对象的private属性");
Field[] fields = class1.getFields();
Field nameField = class1.getDeclaredField(attr);
nameField.setAccessible(true);
nameField.set(p1, "zs_p222"); // name为private 需先解锁权限
System.out.println(nameField.get(p1));
}
// 首字母大写 age >> Age
public static String initcap(String str) {
return str.substring(0, 1).toUpperCase().concat(str.substring(1));
}
}
|
todo-more
泛型,注解等示例
文章作者
duansheli
上次更新
2019-12-25
(325c7b3)