反射

解释:反射是对编译成的class文件进行解析,拿到其属性和方法

  • 首先都是获取类
1
2
3
4
5
6
7
//第一种,通过类名
Class 新名 = 类名.class;
//第二种,通过全类名
Class 新名 = Class.forName("包名.类名");
//第三种,通过对象获得
根据类new一个对象;
Class 新名 = 对象.getClass();
  • 拿到属性
    • 通过field得到属性的类型和名字 得到方法 用method
1
2
3
4
5
6
7
8
9
10
11
12
//得到某个类的所有属性
Field[] fields = 新名.getDeclaredFields();
//得到某个类的带public的所有属性,包括其父类、父类的父类
//Field[] fields = 新名.getFields();
//遍历所有属性并打印名字
for(Fiedl field : fields){
System.out.println(field.getName();
}
//通过属性名字得到属性
Field 新属性名 = 新名.getDeclaredFields("属性名");
//得到属性的基本数据类型
新属性名.getType();
  • 拿到方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//得到某个类的所有方法
Method[] methods = 新名.getDeclaredMethods();
//与field一样也有getMethods()
Method[] methods = 新名.getMethods();
//遍历所有的方法
for(Method method : Methods){
//得到方法名和返回值类型
String str = method.getName() + ":" + method.getReturnType().getTypeName();
//参数列表的遍历(参数列表内不止一个)
Class<?>[] str2 = method.getParameterTypes();
for(Class<?> class1 : str2){
system.out.println(class1.getName());
}
//通过方法名得到方法
//参数列表是基本参数类型的,在反射中得到方法时填入包装类
Method[] methods = 新名.getDeclaredMethods("方法名",参数列表每一个参数的类型的类);
//根据原类创建对象newInstance(),类为People举例,再执行方法invoke()
People p = (People) people.newInstance();
//第一个为对象
方法名.invoke(p,赋的值);
}
  • 反射去泛型
1
2
3
4
5
6
7
8
//创建两个泛型
ArrayList<String> str = new ArrayList<>();
ArrayList<Integer> inte = new ArrayList<>();
//得到泛型的值
Class str1 = str.getClass();
Class inte1 = inte.getClass();
//比较是否是同一个值
system.out.println(str1==inte1);

输出结果为true,验证正确,反射确实是去泛型


反射的实际应用
  • 自定义注解
1
2
3
4
5
6
7
8
9
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RealName {

//属性字段名称 默认空字符串
String name() default "";

}
  • 实体类中属性添加注解 例
1
2
3
4
@RealName(name = "我")
private String me;
@RealName(name = "我的实际名字")
private String myRealName;
  • 反射获取数据
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
//创建map用来接收属性以及其注解的值
Map<String,String> map = new HashMap<>();
try {
//获取类名的包名地址
Class<?> printClass = Class.forName("com.simplemw.user");
//java反射机制获取所有属性
Field[] fields = printClass.getDeclaredFields();
//遍历属性
for (Field field : fields) {
String isNotNullStr = "";
// 判断是否属性上存在注解 RealName
boolean annotationPresent = field.isAnnotationPresent(RealName.class);
if (annotationPresent) {
// 获取自定义注解对象
RealName realName = field.getAnnotation(RealName.class);
// 根据对象获取注解值
isNotNullStr = realName.name();
}
map.put(field.getName(),isNotNullStr);
}
} catch (Exception e) {
e.printStackTrace();
}

//打印测试结果
for (String str:map.keySet()) {
System.out.println(str+"---"+map.get(str));
}