Java反射详解

本文详细介绍了Java反射机制的原理和使用方法,包括如何获取Class对象、创建对象、访问成员变量和方法。通过实例展示了如何通过反射调用构造器、设置私有属性以及执行方法。还探讨了反射的效率问题和权限访问。最后,提供了通过反射调用复杂方法的示例,如在Spring框架中调用服务方法。
摘要由CSDN通过智能技术生成

反射

1.将Java文件保存到本地硬盘
2.编译Java文件,生成.class文件
3.使用Java虚拟机(JVM)将字节码文件加载到内存
4.字节码文件在内存中使用Class类表示
5.使用反射的时候,首先获取到Class类,就可以得到class文件里的所有内容,包含属性、构造方法、普通方法
6.属性通过Filed类表示
7.构造方法通过Constructor表示
8.普通方法通过Method表示

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

万物皆对象,类也是对象;任何一个类都是Class类的一个实例对象,这个对象我们成为该类的类类型

反射的执行效率低,把setassceible设为true可以提高效率

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Apple {
    private String color;
}

得到Class类对象的3种方式

//1
Class clz = Class.forName("cn.zy.pojo.Apple");

//2
Class clz = Apple.class;

//3
Apple apple=new Apple();
Class clz = apple.getClass();//这种方法必须先实例化

通过反射创建对象

Constructor constructor = c.getConstructor(String.class);//有参参构造器

Constructor constructor2 = c.getConstructor();//无参构造器

//初始化
Apple apple1 = (Apple)constructor.newInstance("red");   //有参构造器

Apple apple2 = (Apple)constructor2.newInstance();   //无参构造器

另一种方法

Class clz = Apple.class;
Apple apple = (Apple)clz.newInstance(); //底层调用Class类的newInstance()方法获取构造器

获取构造器

Constructor constructor = c.getConstructor(String.class);//有参参构造器

Constructor constructor2 = c.getConstructor();//无参构造器

//获取私有构造器
Constructor constructor2 = c1.getDeclaredConstructor(String.class);
constructor2.setAccessible(true);//强制清除了java的权限检测,设置可以访问

获取成员变量

成员变量分 public 和 private

获取public成员变量需要 只需要 通过getField(String 属性名)获取;

获取private成员变量需要 通过getDeclaredField(String 属性名)获取,并且 需要必须使用field.setAccessible(true)跳过权限检查;

    Class clz = Apple.class;

    /*Constructor constructor = clz.getConstructor();
    Apple apple = (Apple)constructor.newInstance();*/

    Apple apple = new Apple();
    /*
    获取 public 成员变量,不需要setAccessible(true)
    Field field = clz.getField("color");
    */
    
    //获取私有成员变量getDeclaredField(String 属性名)
    Field field = clz.getDeclaredField("color");
    field.setAccessible(true);  //获取私有成员变量时,必须使用setAccessible(true)跳过权限检查
    field.set(apple,"red");

    System.out.println(apple.toString());

获取成员方法

Class clz = Apple.class;

//得到非私有成员函数并调用这个方法
Method method=  c1.getMethod("setColor",String.class);  //1 方法名,2 方法参数

Apple apple=new Apple();//通过反射得到的对像与new出来的没有区别

//调用方法
method.invoke(apple,"green");

System.out.println(apple.toString());

得到类加载器

Class c = Apple.class;
Object o = c.getClassLoader();

得到这个类实现的所有接口

Class[] interfaces = c1.getInterfaces();

System.out.println(interfaces);

得到配置文件

/*
配置文件的路径(相对路径也可以)
*/
    obj = c1.getResource("/log4j.properties");
    System.out.println(obj);

通过反射调用复杂的方法

@RunWith(SpringRunner.class)
@SpringBootTest
public class MPTest {

    @Resource
    HskstgcpjService hskstgcpjService;

    @Test
    public void t1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //不能传入QueryWrapper.class,不能传入子类 必须 保持一致
        Method method = IraqpjxmServiceImpl.class.getMethod("list", Wrapper.class);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("id");
        Object o = method.invoke(hskstgcpjService,queryWrapper);
    }
}

invoke(对象,参数对象)
注意,getMethod(方法名,参数类型);参数类型必须一致,即使传入子类也不行;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值