一、什么是反射?
在Java中,反射是我们可以通过一个类名来获取它所有的属性和方法,同时也可以调用这些属性和方法。
二、反射的优缺点
反射的优缺点如下:
优点:
- 灵活
缺点:
- 不安全(如无视泛型,相关文章可参考《什么是泛型?有什么用?》)
- 性能较差(因为要做可见性检查、参数检查、参数包装、避开JIT优化等)
三、反射的使用场景
反射的使用场景有以下几个:
- 动态代理:相关文章可参考《Java动态代理》
- JDBC加载:Class.forName加载驱动
- Spring IOC
四、反射的简单使用
1.创建反射目标类
package com.test;
public class User {
private String name;
public void publicMethod(String str) {
System.out.println("publicMethod:" + str);
}
private void privateMethod() {
System.out.println("privateMethod:" + name);
}
}
2.反射操作
public class TestClass {
public static void main(String[] args) throws Exception{
// 获取User的Class对象
Class<?> clazz = Class.forName("com.test.User");
// 初始化User对象
User user = (User) clazz.newInstance();
// 获取User所有方法并打印
Method[] methods = clazz.getDeclaredMethods();
for(Method method : methods) {
System.out.println("method:" + method.getName());
}
// 获取User类指定方法并调用
Method publicMethod = clazz.getDeclaredMethod("publicMethod", String.class);
publicMethod.invoke(user, "public method test");
// 获取User类指定属性并修改
Field field = clazz.getDeclaredField("name");
// 设置该字段可直接访问(由于是private权限,如果不设置就会因为权限校验而不能访问)
field.setAccessible(true);
field.set(user, "private field test");
// 调用private方法
Method privateMethod = clazz.getDeclaredMethod("privateMethod");
// 设置该字段可直接访问(由于是private权限,如果不设置就会因为权限校验而不能访问)
privateMethod.setAccessible(true);
privateMethod.invoke(user);
}
}
输出:
method:publicMethod
method:privateMethod
publicMethod:public method private
privateMethod:private field test