反射的用途及实现&&简单的注解
反射的用途及实现&&简单的注解
反射基本概念
- 反射(reflection)是java的特征之一,允许java程序在运行中能够操作类或者对象内部相关属性(所属类,对象,变量以及方法)。
- 是运行时不是编译时
主要用途
- google出来的都是开发通用框架
- 但是用的最多的应该利用注解以及反射实现一些通用的工具
反射中invoke过程
注解基本概念
- 放张网络图
[来源]: https://www.jianshu.com/p/83cff6b6971e
{% asset_image 5618238-2e8f1e36d062f4d2.png %}
。
实现
下面是将同名对象copy, 并且根据不同的注解进行不同的处理
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
/**
* 注解类
**/
(value = {ElementType.FIELD})
(RetentionPolicy.RUNTIME)
public FieldsValidAnnotation {
// 将double * 100之后转换为Long
boolean doubleMul100ToLong() default false;
// 将double 转换为String
boolean doubleToString() default false;
}
/**
* 转换两个变量name一样,但是不同类型的数据。
*
* @param source 源变量
* @param target 目标变量
*/
public static void copyProties(final Object source, final Object target) {
if (source == null) {
return;
}
Field[] fields = target.getClass().getDeclaredFields();
Method[] targetMethodList = target.getClass().getMethods();
for (Method targetMethod : targetMethodList) {
try {
// 不是set Func 就不
if (!targetMethod.getName().startsWith("set")) {
continue;
}
String fieldName = targetMethod.getName().replaceFirst("set", "");
Field field = target.getClass().getDeclaredField(StringUtils.uncapitalize(fieldName));
field.setAccessible(true);
Method sourceGetMethod = source.getClass()
.getMethod("get" + fieldName, new Class[]{});
Object object = sourceGetMethod.invoke(source, new Object[]{});
object = realConvert(field, object);
targetMethod.invoke(target, object);
} catch (Exception e) {
continue;
}
}
}
/**
* 注解.
**/
private static Object realConvert(Field field, Object object) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().getName().equals(FieldsValidAnnotation.class.getName())) {
if (((FieldsValidAnnotation) annotation).doubleMul100ToLong()) {
object = formatDigit(String.valueOf(object));
}
if (((FieldsValidAnnotation) annotation).doubleToString()) {
object = new BigDecimal(String.format("%.16f", object)).stripTrailingZeros().toString();
}
}
}
return object;
}