Java基础之反射

反射基本介绍

基本过程:

1、编译Java文件,生成.class文件

2、使用Java虚拟机(JVM)将字节码文件(字节码文件在内存中使用Class类表示)加载到内存

4、使用反射的时候,首先获取到Class类,就可以得到class文件里的所有内容,包含属性、构造方法、普通方法

5、属性通过Filed类表示、构造方法通过Constructor表示、普通方法通过Method表示

API学习

接口定义

1
2
3
public interface Pc {
void run();
}

实现类

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
public class Dell implements Pc {

// 私有变量
private String cpu;

public int price;

// 无参构造方法
public Dell() {
}

// 有构造方法
public Dell(String cpu) {
this.cpu = cpu;
}

@Override
public void run() {
System.out.println("Dell PC");
}

public String getCpu() {
return cpu;
}

public void setCpu(String cpu) {
this.cpu = cpu;
}

public int getPrice() {
return price;
}

public void setPrice(int price) {
this.price = price;
}

// 私有方法
private void desc() {
System.out.println("私有方法: 散热不好");
}
}

API学习

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
@Slf4j
public class ReflectEntrance {
public static void main(String[] args) throws Exception{

// 1. Class.forName()
Class<?> dClazz = Class.forName("com.example.ref.Dell");
log.info("Class.forName()=======:{}", dClazz);

// 2. 类名.class
Class<Dell> dClazz2 = Dell.class;
log.info("类名.class=======:{}", dClazz);

// 3. 对象.getClass()
Dell dell = new Dell();
Class<?> dClazz3 = dell.getClass();
log.info("对象.getClass()=======:{}", dClazz3);

System.out.println("\r");

// 获取所有的公共方法(没有private),但是有它所有有关联的类的方法,包括接口,它的父类Object
Method[] methods = dClazz.getMethods();
for (Method method: methods) {
log.info("dClazz.getMethods()=======:{}", method.getName());
}

System.out.println("\r");

// 可以得到当前类的所有的方法: 包括私有的方法
Method[] declaredMethods = dClazz.getDeclaredMethods();
for(Method method : declaredMethods)
log.info("dClazz.getDeclaredMethods()=======:{}", method.getName());

System.out.println("\r");

// 获取Dell实现的所有的接口
Class<?>[] interfaces = dClazz.getInterfaces();
for(Class<?>inter : interfaces)
log.info("dClazz.getInterfaces()=======:{}", inter);

System.out.println("\r");

// 获取公共变量
Field[] fields = dClazz.getFields();
for(Field field : fields)
log.info("dClazz.getFields()=======:{}", field);

System.out.println("\r");

// 获取私有变量
Field[] declaredFields = dClazz.getDeclaredFields();
for(Field field : declaredFields)
log.info("dClazz.getDeclaredFields()=======:{}", field.getName());

System.out.println("\r");

// 获取构造器
Constructor<?>[] constructors = dClazz.getConstructors();
for (Constructor<?> c : constructors)
log.info("dClazz.getConstructors()=======:{}", c);

System.out.println("\r");

// 获取父类
Class<?> superclass = dClazz.getSuperclass();
log.info("dClazz.getSuperclass()=======:{}", superclass); // 默认就是Object

System.out.println("\r");

// 用反射创建实例
Dell dell1 = (Dell)dClazz.newInstance();
log.info("dClazz.newInstance()=======:{}", dell1);
dell1.run();

System.out.println("\r");

// 设置变量
Field cpu = dClazz.getDeclaredField("cpu");
cpu.setAccessible(true);
cpu.set(dell1, "intel");
log.info("设置变量=======:{}", dell1.getCpu());

System.out.println("\r");

// 调用方法
Method setCpu = dClazz.getDeclaredMethod("setCpu", String.class);
setCpu.setAccessible(true);
setCpu.invoke(dell1, "AMD");
log.info("调用方法=======:{}", dell1.getCpu());

System.out.println("\r");

// 操作构造方法
Constructor<?> declaredConstructor = dClazz.getDeclaredConstructor(String.class);
Dell hw = (Dell)declaredConstructor.newInstance("华为");
log.info("构造方法=======:{}", hw.getCpu());

}
}

输出结果

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
23:24:02.109 [main] INFO com.example.ref.ReflectEntrance - Class.forName()=======:class com.example.ref.Dell
23:24:02.117 [main] INFO com.example.ref.ReflectEntrance - 类名.class=======:class com.example.ref.Dell
23:24:02.117 [main] INFO com.example.ref.ReflectEntrance - 对象.getClass()=======:class com.example.ref.Dell

23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:run
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:getPrice
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:setPrice
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:setCpu
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:getCpu
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:wait
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:wait
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:wait
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:equals
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:toString
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:hashCode
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:getClass
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:notify
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:notifyAll

23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:run
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:desc
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:getPrice
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:setPrice
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:setCpu
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:getCpu

23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getInterfaces()=======:interface com.example.ref.Pc

23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getFields()=======:public int com.example.ref.Dell.price

23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredFields()=======:cpu
23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredFields()=======:price

23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getConstructors()=======:public com.example.ref.Dell()
23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getConstructors()=======:public com.example.ref.Dell(java.lang.String)

23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getSuperclass()=======:class java.lang.Object

23:24:02.120 [main] INFO com.example.ref.ReflectEntrance - dClazz.newInstance()=======:com.example.ref.Dell@3a5ed7a6
Dell PC

23:24:02.120 [main] INFO com.example.ref.ReflectEntrance - 设置变量=======:intel

23:24:02.121 [main] INFO com.example.ref.ReflectEntrance - 调用方法=======:AMD

23:24:02.121 [main] INFO com.example.ref.ReflectEntrance - 构造方法=======:华为

有参构造反射

1
2
3
4
5
6
7
8
9
10
public static ConfigService createConfigService(Properties properties) throws NacosException {
try {
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService");
Constructor constructor = driverImplClass.getConstructor(Properties.class);
ConfigService vendorImpl = (ConfigService) constructor.newInstance(properties);
return vendorImpl;
} catch (Throwable e) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e);
}
}

简单演示场景

我们做一个对象转map的演示:

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
/**
* @author 当我遇上你
* @公众号 当我遇上你
* @since 2020-05-28
*/
public class User implements Serializable {
private String username;
private String password;

public User() {
}

public User(String username, String password) {
this.username = username;
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}

通过反射操作字段变量

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
/**
* @author 当我遇上你
* @公众号 当我遇上你
* @since 2020-05-28
*/
@Slf4j
public class BeanUtils {

/**
* 对象转map
* @param o
* @param <T>
* @return
* @throws IllegalAccessException
*/
public static <T> Map<String, Object> obj2map(T o) throws IllegalAccessException {

Class<?> aClass = o.getClass();
Field[] declaredFields = aClass.getDeclaredFields();

Map<String,Object> map = new HashMap<String, Object>();

for (int j = 0; j < declaredFields.length; j++) {
Field declaredField = declaredFields[j];

// 获取属性
String key = declaredField.getName();
declaredField.setAccessible(true);
// 获取属性值
Object value = declaredField.get(o);

log.info("key={}, value={}", key, value == null? "" : value.toString());

map.put(key, value);
}
return map;
}


/**
* map转对象
* @param map
* @param beanClass
* @return
* @throws Exception
*/
public static Object map2Obj(Map<Object, Object> map, Class<?> beanClass) throws Exception {
if (map == null)
return null;

Object obj = beanClass.getDeclaredConstructor().newInstance();

Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
int mod = field.getModifiers();
if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){
continue;
}

Class<?> type = field.getType();
Object o = convertValType(map.get(field.getName()), type);

field.setAccessible(true);
field.set(obj, o);
}

return obj;
}

private static Object convertValType(Object value, Class<?> fieldTypeClass) {
Object retVal = null;
if (Long.class.getName().equals(fieldTypeClass.getName())
|| long.class.getName().equals(fieldTypeClass.getName())) {
retVal = Long.parseLong(value.toString());
} else if (Integer.class.getName().equals(fieldTypeClass.getName())
|| int.class.getName().equals(fieldTypeClass.getName())) {
retVal = Integer.parseInt(value.toString());
} else if (Float.class.getName().equals(fieldTypeClass.getName())
|| float.class.getName().equals(fieldTypeClass.getName())) {
retVal = Float.parseFloat(value.toString());
} else if (Double.class.getName().equals(fieldTypeClass.getName())
|| double.class.getName().equals(fieldTypeClass.getName())) {
retVal = Double.parseDouble(value.toString());
} else {
retVal = value;
}
return retVal;
}

public static void main(String[] args) throws Exception{
User user = new User("admin", "123456");
Map<String, Object> map = BeanUtils.obj2map(user);
System.out.println(map);
Object o = BeanUtils.map2Obj(map, User.class);
System.out.println(o);
}

}

输出

1
2
{password=123456, username=admin}
User{username='admin', password='123456'}

最后

本文到此结束。感谢阅读,如果您觉得不错,请关注公众号【当我遇上你】支持一下。