JAVA反射

一、概述

什么是反射

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

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象

总之,反射就是把java类中的各种成分映射成一个个的Java对象。例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象

反射机制是Java特性之一,反射机制是构建框架技术的基础所在。

反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高。

二、Java反射的核心类库

核心类

Java反射机制主要涉及以下四个核心类库:

Class类:反射的核心类,反射所有的操作都是围绕该类来生成的,通过它,可以获取类的属性,方法等内容。

Field类:表示类的属性,可以获取和设置类中属性的值。

Method类:表示类的方法,它可以用来获取类中方法的信息,或者执行方法。

Constructor类:表示类的构造方法。

关于Class类

(1)Class 是一个特殊的类,但它和一般类一样继承自Object。

(2)Class是Reflection故事起源,针对任何你想使用反射技术的类,必须先为它产生一个Class 对象。

(3)Class包含的信息有某个类的数据成员名、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个类的有关信息。

(4)Class 对象只能由系统建立对象。

(5)一个类在 JVM 中只会有一个Class实例。

(6)每个类的实例都会记得自己是由哪个 Class 实例所生成。

三、Class对象功能

1,获取成员变量们

Field[] getFields() :获取所有public修饰的成员变量

Field getField(String name) 获取指定名称的 public修饰的成员变量

Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符

Field getDeclaredField(String name)

2,获取构造方法们

Constructor<?>[] getConstructors()

Constructor<T> getConstructor(类<?>... parameterTypes)

Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)

Constructor<?>[] getDeclaredConstructors()

3,获取成员方法们:

返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口的公共 member 方法。

Method[] getMethods()

Method getMethod(String name, 类<?>... parameterTypes)

返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

Method[] getDeclaredMethods()

Method getDeclaredMethod(String name, 类<?>... parameterTypes)

也就是说getDeclaredMethods能拿到所有(不包括继承的方法),而getMethods只能拿到public方法(包括继承的类或接口的方法)

4,获取全类名

String getName()

String getSimpleName():类名

四、Java反射的基本使用

1,获取Class对象

要使用反射,首先需要获取目标类的Class对象。有以下几种方式:

(1)通过类的class属性获取:

Class clazz = String.class;

(2)通过对象的getClass()方法获取:

String str = "hello";
Class clazz = str.getClass();

(3)通过Class.forName()方法获取:

Class clazz = Class.forName("java.lang.String");

2,创建对象

通过Class对象的newInstance()方法可以创建一个实例,但前提是该类有默认的无参构造方法:

Object obj = clazz.newInstance();

如果目标类没有无参构造方法,可以通过Constructor类来创建对象:

Constructor constructor = clazz.getConstructor(String.class);
Object obj = constructor.newInstance("hello");

如果需要调用目标私有的构造方法,则用通过getDeclaredConstructor类来构造对象:

 Constructor constructor2 = cls.getDeclaredConstructor(String.class, int.class);
//得到私有的构造方法
     
        //暴力反射,解除封装
        constructor2.setAccessible(true);
        Student student3 = (Student) constructor2.newInstance("12", 12);

3,获取属性

要获取一个类的公共属性,可以使用Class类的getFields()方法。这个方法返回一个包含类的所有公共属性的Field对象数组:

 Field[] fields = cls.getFields();//获取公共的属性的数组
        for (Field field : fields) {
            System.out.println(field.getName());
        }

要获取一个类的私有属性,需要使用Class类的getDeclaredFields()方法。这个方法返回一个包含类的所有属性(包括私有属性)的Field对象数组:

Field[] fields1 = cls.getDeclaredFields();//获取私有的属性数组
        for (Field field : fields1) {
            System.out.println(field.getName());
        }

根据属性名获取单个属性并设置值:

Field cex = cls.getField("cex");//获取公开的单个属性
        cex.set(student1, "12");//设置值,对象+值

        Field name = cls.getDeclaredField("name");//获取私有的单个属性
        //解除封装
        name.setAccessible(true);
        name.set(student1, "小明");//设置值,对象+值

4,调用方法

通过Method类可以调用目标对象的方法,包括私有方法。

公开方法:

Method method = cls.getMethod("eat");//得到指定的公开的成员方法
        method.invoke(student1);//调用方法,方法名.invoke(对象)

私有方法:

Method method2 = cls.getDeclaredMethod("Study");//得到指定的私有的成员方法
        method2.setAccessible(true);
        method2.invoke(student1);//调用方法,方法名.invoke(对象)

如果方法有参数,需要在getMethod()方法中传入参数类型:

Method method1 = cls.getMethod("sheep", String.class);//String.class为字解码
        method1.invoke(student1, "李华");//调用方法,对象+值

五、Java反射的应用场景

ORM框架:如Hibernate、MyBatis等,通过反射实现数据库表与Java对象的映射。

JSON解析:如Fastjson、Gson等,通过反射将JSON字符串转换为Java对象。

动态代理:如Spring AOP,通过反射创建代理对象,实现方法拦截和增强。

单元测试:如JUnit,通过反射调用测试方法。

总结

Java反射机制是一种在运行时动态获取类信息、创建对象、调用方法、访问字段的能力,它提供了程序的灵活性和扩展性,但同时也可能带来性能下降和安全隐患。正确使用反射可以简化代码、实现框架设计,但需注意避免滥用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值