JAVA反射机制

JAVA在JDK1.5之后引入了反射机制,通过反射,使得我们在程序运行时可以动态根据方法名实现调用,可以便利对象属性、在我们不知道具体某个对象的类型时可以通过反射获取等等。其实这些一个最基本的作用和就是内省。

下面这个脑图是在网上拿到的:

比较常见用法:

package practice.base;

import com.hbnnmall.hbnnmallproduct.dto.GoodsDetailRequest;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class ReflectionPra {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, IntrospectionException, InvocationTargetException {
        GoodsDetailRequest goodsDetailRequest = new GoodsDetailRequest();
        goodsDetailRequest.setGid(244L);
        Class<?> cl = goodsDetailRequest.getClass();
        System.out.println(cl.getName());
        System.out.println(cl.getClassLoader());
        System.out.println(Arrays.toString(cl.getDeclaredConstructors()));
        System.out.println(Class.forName("com.hbnnmall.hbnnmallproduct.dto.GoodsDetailRequest"));
        Field[] fields = cl.getDeclaredFields();
        System.out.println(Arrays.toString(fields));
        //遍历属性
        for (Field field:fields){
            field.setAccessible(true);
            System.out.println(field.getName());
            System.out.println(field.get(goodsDetailRequest));
            PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), cl);
            Method method = descriptor.getReadMethod();
            Object value = method.invoke(goodsDetailRequest);
            System.out.println(value);
        }


    }
}

JAVA反射主要是通过类Class对象 和java.lang.reflect实现的。

1、Class

对于JAVA来讲,在编译时,会将我们写的程序编译成字节码,JVM的类加载器会读取字节码文件(.class)文件,随后会经历验证解析等阶段,具体的可以看我之前写的文章: JAVA类加载以及SPI机制

CLass对象作为元信息会被存储在方法区。

当我们在执行一个对象创建时,比如

GoodsDetailRequest goodsDetailRequest = new GoodsDetailRequest();

首先会根据GoodsDetailRequest的全限定名去查找GoodsDetailRequest.class对象。然后通过类加载器创建GoodsDetailRequest对象。

通常我们在获取Class对象时,可以通过Class.forName获取,也可以通过某个类的.class获取,也可以通过对象实例的getClass获取。

2、java.lang.reflect

java.lang.reflect 包的核心接口和类如下:

  • Member 接口:反映关于单个成员(字段或方法)或构造函数的标识信息。
  • Field 类:提供一个类的域的信息以及访问类的域的接口。
  • Method 类:提供一个类的方法的信息以及访问类的方法的接口。
  • Constructor 类:提供一个类的构造函数的信息以及访问类的构造函数的接口。
  • Array 类:该类提供动态地生成和访问 JAVA 数组的方法。
  • Modifier 类:提供了 static 方法和常量,对类和成员访问修饰符进行解码。
  • Proxy 类:提供动态地生成代理类和类实例的静态方法。

除了我们上面例子的基本使用,我们最常用的一个场景就是生曾动态代理。动态代理就是通过反射的机制来实现的。动态代理相关的知识,之前我也写过一篇文章: JAVA代理及Dubbo与Springboot的应用

参考资料:

深入理解JAVA反射

JAVA反射

--------EOF---------
微信分享/微信扫码阅读