反射基本介绍
基本过程:
1、编译 Java 文件,生成.class 文件
2、使用 Java 虚拟机(JVM)将字节码文件(字节码文件在内存中使用 Class 类表示)加载到内存
4、使用反射的时候,首先获取到 Class 类,就可以得到 class 文件里的所有内容,包含属性、构造方法、普通方法
5、属性通过 Filed 类表示、构造方法通过 Constructor 表示、普通方法通过 Method 表示
API 学习
接口定义
public interface Pc {
void run();
}
实现类
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 学习
@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());
}
}
输出结果
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 - 构造方法=======:华为
简单演示场景
我们做一个对象转 map 的演示:
public class User {
private String username;
private String password;
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;
}
}
通过反射操作字段变量
@Slf4j
public class Test {
public <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.toString());
map.put(key, value);
}
return map;
}
public static void main(String[] args) throws Exception {
Test test = new Test();
User user = new User("admin", "123456");
Map<String, Object> map = test.obj2map(user);
log.info(map.toString());
}
}
输出
23:52:41.964 [main] INFO com.example.poi.Test - key=username, value=admin
23:52:41.970 [main] INFO com.example.poi.Test - key=password, value=123456
23:52:41.970 [main] INFO com.example.poi.Test - {password=123456, username=admin}
最后
本文到此结束。感谢阅读,如果您觉得不错,请关注公众号【当我遇上你】支持一下。