当前位置:

首页 > 编程开发 > Java反射机制是什么及怎么实现

Java反射机制是什么及怎么实现

1.通过反射,我们可以构建实例,得到成员变量的值,得到方法并调用。还可以获得定义在成员变量、方法、方法参数上的注解。接下来看代码实现,然后讲原理。1)构建无参实例:通过反射调用无参构造函数//1.通过全类名加载字节码对象Classclazz=Class.forName("com.example.lib.Person");//2.通过类的字节码拿到定义的构造函数Constructorconstructor=clazz.getConstructor();//3.通过构造方法创建对象Objectobj=cons

本文目录

    1.通过反射,我们可以构建实例,得到成员变量的值,得到方法并调用。

    还可以获得定义在成员变量、方法、方法参数上的注解。

    接下来看代码实现,然后讲原理。

    1)构建无参实例:通过反射调用无参构造函数

            //1.通过全类名加载字节码对象
            Class clazz = Class.forName("com.example.lib.Person");
            //2.通过类的字节码拿到定义的构造函数
            Constructor constructor = clazz.getConstructor();
            //3.通过构造方法创建对象
            Object obj = constructor.newInstance();

    2)构建有参数实例:

            //1.通过全类名加载字节码对象
            Class clazz = Class.forName("com.example.lib.Person");
            //2.通过类的字节码拿到定义的构造函数
            Constructor constructor = clazz.getConstructor(int.class,String.class);
            //3.通过构造方法创建对象
            Object obj = constructor.newInstance(20,"xiaohua");

    3)通过反射获取成员变量的值。

            //4.通过属性名获取属性
            Field field = clazz.getDeclaredField("age");
            field.setAccessible(true);
            //5.调用get方法拿到对象obj属性age的值
            Integer age = (Integer) field.get(obj);

    4)通过反射调用对象的方法。

            //4.通过方法名和参数类型,拿到方法
            method = clazz.getMethod("setAge", int.class);
            //5.调用方法 obj是哪个对象身上的方法。
            method.invoke(obj, 21);
            method =  clazz.getMethod("getAge");
            method.invoke(obj);

    5).通过反射获取静态变量的值。

           //1.通过全类名加载字节码对象
            Class clazz = Class.forName("com.example.lib.Person");
            //2.获取静态属性ID
            Field  field = clazz.getField("ID");
            field.setAccessible(true);
            //3.拿到静态属性ID的值。
            // 因为静态变量存在方法区,在对象创建之前,就已经加装到了内存
            //所以,没有对象,也可以获取变量的值,这里传null也是可以的。
            int id = (int) field.get(null);

    2.通过反射获取定义的注解的值

    1)获取成员变量的注解以及值。

    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface BindView {
        int value();
    }
    public class MainActivity {
        @BindView(10000)
        TextView textView;
    }
            //10通过反射拿到定义在属性上的注解
            Class  clazz = MainActivity.class;
            Field textView = clazz.getDeclaredField("textView");
            BindView bindView = textView.getAnnotation(BindView.class);
            int txtId = bindView.value();

    3)通过反射获取定义在方法和方法参数上的注解以及值

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Post {
        String value() default "";
    }
    public interface NetWorkInterface {
        @Post("http://www.baidu.com")
        Call getPerson(@Queue("name") String name, @Queue("200") int price);
    }
          //11通过反射拿到方法上定义的注解
            clazz = NetWorkInterface.class;
            Method method = clazz.getMethod("getPerson", String.class, int.class);
            //获取Post注解
            Post post = method.getAnnotation(Post.class);
            //获取值
            String url = post.value();
             //12通过反射拿到参数上的注解
            //为是个二维数组,因为方法参数会有多个,一个参数有可能定义多个注解
            Annotation[][] annotations = method.getParameterAnnotations();
            for (Annotation[] ans : annotations) {
                for (Annotation an : ans) {
                    if (an instanceof Queue) {
                        Queue queue = (Queue) an;
                        String value = queue.value();
                    }
                }
            }

    4)获取方法的参数和返回值类型。

            //13.拿到方法参数的类型。
            Type[] types = method.getGenericParameterTypes();
            for (Type type : types) {
                System.out.println(type.toString());
            }
            //14.获取方法返回值类型
            Type type = method.getGenericReturnType();

    3总结:通过反射,可以拿到对象身上的成员变量的值、调用方法,获取定义在成员变量、方法和 方法参数上的注解。Retrofit 就用到了注解加反射技术,和动态代理(这个技术稍后分享)

    4.通过反射,可以做到以上事情。反射的原理是啥?

    1)我们写的源代码是.java文件,通过javac编译后成为.class文件,即字节码文件。

    2)程序执行时,JVM会类加载字节码文件到内存,严格意义上说是加载到方法区,并转换成

    java.lang.Class对象。万事万物皆对象,Class被称为类对象,描述类在元数据空间的数据结构,包含类中定义的属性、方法、构造方法、注解、接口等信息。

    所有反射的第一步是拿到类对象Class对象。拿到了Class对象,也就拿到了类中定义的一切。

    Class clazz = Class.forName("com.example.lib.Person");

    这行代码就是通过类加载器把Person类加载到内存,并得到对应的Class 对象。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。