《Java反射机制》
目录
一、概念简介
程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为Java的反射机制(广泛用于各个框架中用于类之间的解耦,比如说Spring的IOC实现)。
Class类
反射机制很重要的一点就是“运行时”。注意:JVM并不是在一开始就把所有的类都加载到内存中,而是到用的时候才把它加载进来。当Java虚拟机载入一个类的时候,它就会自动创建一个Class类的实例来表示这个类,该实例中包含了完整的类的结构信息。这个对象就像一面镜子将类的结构展示给我们,所以我们形象的称之为“反射”。

二、镜像获取
Cat类
package com.hpr.entity;
public class Cat {
private String name;
private int age;
private double weight;
public Cat() {
}
public Cat(String name, int age, double weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public void speak() {
System.out.println(name + "正在喵喵喵...");
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
", weight=" + weight +
'}';
}
}
镜像对象获取(熟练)
//方式一:类.class
Class<Cat> clazz1 = Cat.class;
//方式二:对象.getClass()
Cat cat = new Cat();
Class<? extends Cat> clazz2 = cat.getClass();
//方式三1:Class.forName全路径引入
try {
Class<?> clazz3= Class.forName("com.hpr.entity.Cat");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class类常用方法(了解)
boolean isPrimitive = clazz1.isPrimitive(); //判断是否是基础类型
boolean isArray = clazz1.isArray(); //判断是否是集合类
boolean isAnnotation = clazz1.isAnnotation(); //判断是否是注解类
boolean isInterface = clazz1.isInterface(); //判断是否是接口类
boolean isEnum = clazz1.isEnum(); //判断是否是枚举类
boolean isAnonymousClass = clazz1.isAnonymousClass(); //判断是否是匿名内部类
boolean isAnnotationPresent = clazz1.isAnnotationPresent(Deprecated.class);//判断是否被某个注解类修饰
String className = clazz1.getName(); //获取class名字 包含包名路径
Package aPackage = clazz1.getPackage(); //获取class的包信息
String simpleName = clazz1.getSimpleName(); //获取class类名
int modifiers = clazz1.getModifiers(); //获取class访问权限
三、镜像操作
创建对象(镜像方式)
Cat cat1 = clazz1.newInstance();
构造获取(了解)
Constructor<?>[] cs = clazz1.getConstructors(); //获取常规构造
Constructor<?>[] dcs = clazz1.getDeclaredConstructors(); //获取所有构造(包含private)
Constructor<? extends Cat> cst = clazz1.getConstructor(int.class, String.class, int.class); //获取指定构造
Cat cat2 =cst.newInstance(1001,"汤姆",2); //使用构造创建对象
字段获取(掌握)
Field[] fs = clazz1.getFields(); //获取常规字段
Field[] dfs = clazz1.getDeclaredFields(); //获取所有字段(包含private)
Field name = clazz1.getDeclaredField("name"); //获取指定字段
name.setAccessible(true); //设置可访问性为true
name.set(cat1, "汤姆"); //赋值
System.out.println(name.get(cat1)); //取值
方法获取(掌握)
Method[] ms = clazz1.getMethods(); //获取常规方法
Method[] dms = clazz1.getDeclaredMethods(); //获取所有方法(包含private)
Method speak = clazz1.getMethod("speak"); //获取指定方法
speak.invoke(cat1); //执行方法
四、场景模拟
- 对象转Map
public static <T> Map<String, Object> beanToMap(T t) {
Map<String, Object> map = new HashMap<>();
Class<?> clazz = t.getClass();
Field[] dfs = clazz.getDeclaredFields();
for (Field df : dfs) {
df.setAccessible(true);
try {
map.put(df.getName(), df.get(t));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return map;
}
- Map转对象
public static <T> T mapToBean(Map<String, Object> map, Class<T> clazz) {
T t = null;
try {
t = clazz.newInstance();
for (Field df : clazz.getDeclaredFields()) {
df.setAccessible(true);
if (map.containsKey(df.getName())) {
df.set(t, map.get(df.getName()));
}
}
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return t;
}
- 测试
Cat c1 = new Cat(1001, "汤姆", 2);
Map<String, Object> map = beanToMap(c1);
System.out.println(map);
Cat c2 = mapToBean(map, Cat.class);
System.out.println(c2);
执行结果

总结
重点
- Java反射相关概念;
- 镜像对象获取;
- 反射中字段、方法的设置及使用。
难点
- Java反射相关概念;
- 反射中字段、方法、构造的设置及使用。
本文介绍了Java反射机制的基本概念,包括如何获取类的镜像对象,通过Class类的不同方法进行类、构造器、字段和方法的访问与操作。此外,还展示了如何利用反射进行对象的创建和方法的调用,并提供了对象转Map和Map转对象的场景模拟。
1032

被折叠的 条评论
为什么被折叠?



