仿写Dubbo-Java反射

news2024/9/26 3:19:24

概念

反射是Java的一个特性,反射允许程序运行时动态获取类的所有信息以及对其进行操作。反射在框架(spring,springboot,mybatis等)中的使用非常的广发,可谓是框架的灵魂。

获取Class对象

在使用反射之前,需要获取到Class对象,获取到对象之后才可以对其进行操作。Java提供了三个获取Class对象的方法:

public class App {
    public static void main(String[] args) {
        
    }
}

①.getClass()

.getClass()是Object类的方法,对象实例化之后可以调用该方法获取到Class对象。因为Java中的所有类隐式继承了Object类,所以每个类都包含.getClass()方法。

    public static void main(String[] args) {
        App app = new App();
        //根据实例获取类
        Class appClass = app.getClass();
    }

②.class

类直接.class就能获取Class对象。

    public static void main(String[] args) {
        Class appClass = App.class;
    }

③Class.forName("classFullName")

这种方式与前俩各种不太一样,前两者在有了类之后才可以获取Class对象。这种方式根据全类名获取到类的Class对象,错误输入全类名会导致错误,所以需要捕获异常

    public static void main(String[] args) {
        try {
            Class appClass = Class.forName("com.agi.App");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在反射中,第三种方式用的比较多。

反射应用

创建Action接口

public interface Action {
    void doSomething(String param);
}

创建Anno注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Anno {
}

创建App类

@Anno
public class App implements Action {
    private String name;
    public int count;

    public App() {
    }

    public App(String name, int count) {
        this.name = name;
        this.count = count;
    }

    private void print() {
        System.out.println(name + count);
    }
    @Override
    public void doSomething(String param) {
        System.out.println(name + "\t" + param);
    }
    public static void main(String[] args) {
      
    }
}

获取注解

 

    public static void main(String[] args) {
        try {
            Class app = Class.forName("com.agi.App");
            //根据类型获取注解
            Annotation annotation = app.getAnnotation(Anno.class);
            //获取所有注解
            Annotation[] declaredAnnotations = app.getDeclaredAnnotations();
            for (Annotation declaredAnnotation : declaredAnnotations) {
                System.out.println(declaredAnnotation);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//    打印结果
//    @com.agi.Anno()

获取类实现的接口

    public static void main(String[] args) {
        try {
            Class app = Class.forName("com.agi.App");
            Class[] interfaces = app.getInterfaces();
            for (Class inter : interfaces) {
                System.out.println(inter);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 打印结果
    // interface com.agi.Action

获取构造方法

 

    public static void main(String[] args) {
        try {
            Class app = Class.forName("com.agi.App");
            //根据参数类型获取公有构造器
            Constructor constructor = app.getConstructor(new Class[]{String.class, int.class});
            //根据参数类型获取构造器
            Constructor declaredConstructor = app.getDeclaredConstructor(new Class[]{String.class, int.class});
            //获取所有公有构造器
            Constructor[] constructors = app.getConstructors();
            //获取所有构造器
            Constructor[] declaredConstructors = app.getDeclaredConstructors();
            for (Constructor c : declaredConstructors) {
                System.out.println(c);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//    打印结果
/*    public com.agi.App()
      public com.agi.App(java.lang.String,int)    */

实例化对象

    public static void main(String[] args) {
        try {
            Class app = Class.forName("com.agi.App");
            //使用默认构(无参)造方法实例化对象
            Object instance = app.newInstance();
            Constructor appConstructor = app.getConstructor();
            instance = appConstructor.newInstance();
            //使用公有构造器实例化对象
            Constructor constructor = app.getConstructor(new Class[]{String.class, int.class});
            Object constructorInstance = constructor.newInstance("hi", 12);
            //使用构造器实例化对象
            Constructor declaredConstructor = app.getDeclaredConstructor(new Class[]{String.class, int.class});
            Object declaredConstructorInstance = declaredConstructor.newInstance("hi", 30);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

获取成员变量

 

    public static void main(String[] args) {
        try {
            Class app = Class.forName("com.agi.App");
            //据名称获取公有成员变量
            Field count = app.getField("count");
            //根据名称获取成员变量
            Field name = app.getDeclaredField("name");
            //获取所有公有成员变量
            Field[] fields = app.getFields();
            //获取所有成员变量
            Field[] declaredFields = app.getDeclaredFields();
            for (Field field : declaredFields) {
                System.out.println(field);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
//    打印结果
//    private java.lang.String com.agi.App.name
//    public int com.agi.App.count

成员变量赋值

    public static void main(String[] args) {
        try {
            Class app = Class.forName("com.agi.App");
            //使用默认构(无参)造方法实例化对象
            Object instance = app.newInstance();
            //获取成员变量
            Field name = app.getDeclaredField("name");
            //赋值
            name.set(instance, "hello");
            System.out.println(name.get(instance));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//    打印结果
//    hello

获取成员方法

 

    public static void main(String[] args) {
        try {
            Class app = Class.forName("com.agi.App");
            //根据方法名获取公有方法
            Method doSomething = app.getMethod("doSomething", String.class);
            //根据方法名获取方法
            Method print = app.getDeclaredMethod("print");
            //获取所有公有方法(包括Object类的方法)
            Method[] methods = app.getMethods();
            //获取该类的所有方法
            Method[] declaredMethods = app.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                System.out.println(declaredMethod);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//    打印结果
/*    public void com.agi.App.doSomething(java.lang.String)
      public static void com.agi.App.main(java.lang.String[])
      private void com.agi.App.print()    */

成员方法调用

    public static void main(String[] args) {
        try {
            Class app = Class.forName("com.agi.App");
            //使用默认构(无参)造方法实例化对象
            Object instance = app.newInstance();
            //获取成员方法
            Method method = app.getMethod("doSomething", String.class);
            method.invoke(instance, "hello");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//    打印结果
//    null	hello

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/175610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工欲善其事必先利其器——Elasticsearch安装

安装使用说明 首先在elasticsearch官网下载你想要安装的版本,我这里使用的是7.12.1版本 上传到你想要安装的目录(/user/search/) 然后解压,解压命令如下: tar -zxvf elasticsearch-7.12.1-linux-x86_64.tar.gz 解压后…

创建保存字符串的数组numpy.char以及用于处理字符串数组的函数

【小白从小学Python、C、Java】【计算机等级考试500强双证书】【Python-数据分析】创建字符串数组numpy.char.array()修改字符串数组大小写capitalize();title();lower();upper()[太阳]选择题对于以下python代码title()方法输出的结果是?imp…

【并发编程十二】c++20线程同步——信号量(semaphore)

【并发编程十二】c20线程同步——信号量(semaphore)一、互斥二、条件变量三、future四、信号量1、信号量原理2、c 20 信号量3、demo简介: 本篇文章,是线程同步的最后一篇。我们详细的介绍下c标准库提供的线程同步方法——信号量&a…

嵌入式Linux-线程创建与终止

1. 线程的创建 1.1 创建线程 启动程序时,创建的进程只是一个单线程的进程,称之为初始线程或主线程,本小节我们讨论如何创建一个新的线程。 创建线程与创建进程的方法是一样的,让我们来看一下创建线程的函数: #incl…

Linux基本功系列之chown命令实战

文章目录一. 前言🚀🚀🚀二. chown命令介绍三. 语法格式及常用选项四. 参考案例3.1 改变指定文件的属组和属主3.2 改变指定文件的所属主与所属组,并显示过程3.3 改变指定目录及其内所有子文件的所属主与所属组3.4 只修改文件所属组…

P问题、NP问题、NP-Complete问题、NP-Hard问题分别代表什么含义?

绪论 在了解P、NP、NP-Complete、NP-Hard问题之前,先感性地感受一下这几个问题之间的区别和联系👇: 上图分为左右两个版本,推荐记住左边的比较通用。这是因为NP=P这个数学问题曾经被列为7大数学难题之一,而且是之首,甚至美国还悬赏100W美金,但是比较认可的结果是暂时…

Python数据可视化之条形图和热力图

Python数据可视化之条形图和热力图 提示:介绍 简单介绍Pthon可视化的图表使用 提示:热力图和条形图 文章目录Python数据可视化之条形图和热力图前言一、导入数据包二、选择数据集2.加载数据2.读入数据总结前言 提示:这里可以添加本文要记录的…

Acwing 1010. 拦截导弹

Acwing 1010. 拦截导弹一、问题描述二、算法分析三、代码实现一、问题描述 二、算法分析 这道题共分为两问,我们先看第一问。 该问的背后是一个很经典的最长单调子序列模型。 在这个模型中,我们的状态f[i]f[i]f[i]的定义是,以第iii个元素为结…

Cert Manager 申请SSL证书流程及相关概念-三

中英文对照表 英文英文 - K8S CRD中文备注certificatesCertificate证书certificates.cert-manager.io/v1certificate issuersIssuer证书颁发者issuers.cert-manager.ioClusterIssuer集群证书颁发者clusterissuers.cert-manager.iocertificate requestCertificateRequest证书申…

50个你离不开的 CLI 工具

作为开发人员,我们在终端上花费了大量时间。有很多有用的 CLI 工具,它们可以让您在命令行中的生活更轻松、更快速,而且通常更有趣。这篇文章概述了我最依赖的 50 个必备 CLI 工具。如果我遗漏了什么 - 请在评论中告诉我 :)在本文的结尾&#…

二叉树专题汇总

二叉树的前中后序遍历day11|144.二叉树的前序遍历、145.二叉树的后序遍历、94.二叉树的中序遍历_奈川直子的博客-CSDN博客二叉树的层序遍历、翻转二叉树、对称二叉树day12|层序遍历合集、226.翻转二叉树、101.对称二叉树_奈川直子的博客-CSDN博客N叉树最大深度、完全二叉树节点…

LCHub:2023年无代码、低代码8大技术趋势

在数字化转型、新冠疫情、全球经济环境动荡等多因素驱动下,使得组织改变了对低代码、无代码的看法,市场规模和场景化落地实现快速增长。根据Gartner预测,到2025年,70%的应用程序将由低代码和无代码开发平台构建,其中 80%的应用程序由非IT工作者开发而成。 没有编程背景的…

青山不语,碧海无痕,数字山河间的中国脊梁

刚刚过去的2022,对于新农人来说,是不寻常的一年。福建宁德的渔民祖祖辈辈都以外出打鱼为生,渔排生活条件艰苦,娱乐匮乏,销路也不稳定,这种苦闷正随着AI、直播等数字新技术的到来而被消解。青海列卜加村的孙…

Arduino的nodemcu 8266开发板使用MicroPython开发的整体流程

程序安装准备 安装开发板驱动,官网:(https://cn.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tabdownloads)这里不是CH340驱动,而是CP210x USB to USART 驱动,最终也是在“设备管理器查看COM口…

【LeetCode:33. 搜索旋转排序数组~~~二分】

题目描述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…

操作系统真相还原_第5章第1节:利用BIOS中断0x15 获取内存信息

文章目录功能号返回信息功能号详解子功能号&#xff1a;0xE820子功能号&#xff1a;0xE801子功能号&#xff1a;0x88内存检测示例当前内存分布说明程序boot.incmbr.sloader.s编译并写入硬盘启动bochs运行功能号 EAX0xE820&#xff1a;遍历主机上全部内存 AX0xE801&#xff1a;…

分享121个ASP源码,总有一款适合您

ASP源码 分享121个ASP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 121个ASP源码下载链接&#xff1a;https://pan.baidu.com/s/1wwsIoZidHihm5WHPKjlvMg?pwdew3b 提取码&#x…

如何在linux服务器部署sonar服务?

文章目录前言一、上传sonar插件二、设置sonar插件的权限三、启动插件四、配置环境变量前言 sonar服务是代码质量扫描的工具,我们如何利用sonar进行代码质量扫描还有在linux服务器上部署呢?下面这篇文章详细的记录了我在sonar的使用过程中所遇到的各种坑。 一、上传sonar插件…

十大经典排序算法【算法思想+图解+代码】【数据结构与算法笔记】

前言&#xff1a;文中大部分为本人收集整理&#xff0c;综合学习资料&#xff0c;个人理解……。希望能帮助你少掉写头发&#xff0c;早日走出理解的深渊。因为写作较为仓促文中内容难免会有纰漏&#xff0c;发现可评论区回复&#xff08;无奖&#xff09;。排序(Sort)分析排序…

StudioOne6旗舰版DAW2023跨版本升级新功能介绍

PreSonus2023发布了Studio One 6旗舰级DAW的跨版本升级。他们获奖的DAW软件的这一最新版本引入了大量的新功能和增强功能&#xff0c;包括用户界面的定制选项&#xff0c;PreSonus说这使第6版成为他们迄今为止最个性化的升级。PreSonus发布了旗舰级DAW的跨版本升级&#xff0c;…