Java的反射

news2024/11/16 6:34:18

1.反射的定义

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

2.反射的作用

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理

3.反射的使用

在运行时创建新类对象在使用Java的反射功能时,首先都要获取类的Class对象,再通过Class对象进行下一步的操作

首先创建一个类作为例子

public class User {
    public Integer userid;
    private String username;
    private String sex;

    public User() {
    }

    public User(Integer userid, String username, String sex) {
        this.userid = userid;
        this.username = username;
        this.sex = sex;
    }

    public User(Integer userid, String username) {
        this.userid = userid;
        this.username = username;
    }

    public Integer getUserid() {
        return userid;
    }

    public String getUsername() {
        return username;
    }

    public String getSex() {
        return sex;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User{" +
                "userid=" + userid +
                ", username='" + username + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }

    public int method1() {
        System.out.println("这是无参方法1");
        return 0;
    }

    public int method2(Integer n) {
        System.out.println("这是有参方法2,传入参数为:" + n);
        return 0;
    }

    private int method3() {
        System.out.println("这是私有方法3");
        return 0;
    }
}

1)获取Class对象的三种方式

// 一:通过全限定名获取类对象
Class userClass = Class.forName("User");
System.out.println(userClass);
 
// 二:通过类直接获取类对象
Class userClass1 = User.class;
System.out.println(userClass1);
 
// 三:通过类实例获取对象
User user = new User();
Class userClass2 = user.getClass();
System.out.println(userClass2);
System.out.println(userClass.equals(userClass1));
System.out.println(userClass1.equals(userClass2));

运行结果:
在这里插入图片描述

2) Class对象的api

Class api: https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html

常用的api有一下几个:

getName():获得类的完整名字。

getFields():获得类的public类型的属性。

getDeclaredFields():获得类的所有属性。包括private 声明的和继承类

getMethods():获得类的public类型的方法。

getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类

getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。

getConstructors():获得类的public类型的构造方法。

getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。

newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

2.1 ) getDeclaredFields() 和 getField()方法的区别

/**
 * getDeclaredFields() 和  getField()方法的区别
 */
Field [] fields =  userClass.getFields();
Field [] declaredFields =  userClass.getDeclaredFields();
 
for(Field item : fields) {
    System.out.println("fields ---> " + item.getName());
}
 
for(Field item : declaredFields) {
    System.out.println("Declared --- >" + item.getName());
}

运行结果:

在这里插入图片描述

getField()只能获取公共属性,getDeclaredFields() 可以获取所有属性

2.2)newInstance的使用

		//无参构造方法
        User userParam1 = (User) userClass.newInstance();

        System.out.println("----userid--" + userParam1.getUserid());
        System.out.println("----username--" + userParam1.getUsername());
        System.out.println("----usersex--" + userParam1.getSex());

        //有参构造方法
        Constructor constructor = userClass.getConstructor(Integer.class,String.class);
        User userParam = (User) constructor.newInstance(12,"zhangsan");

        System.out.println("----userid--" + userParam.getUserid());
        System.out.println("----username--" + userParam.getUsername());
        System.out.println("----usersex--" + userParam.getSex());

运行结果:

在这里插入图片描述

newInstance()如上面描述的通过无参构造来获取实例化对象,如果想调用有参构造来实例化对象按照上面代码中有参构造方法的调用方法(即先创建有参构造器):

2.3)方法获取与调用

		//无参方法调用
        Method method1 = userClass.getMethod("method1",new Class []{});
        method1.invoke(constructor.newInstance(12,"zhangsan"),new Object[]{});


        //有参方法调用
        Method method2 = userClass.getMethod("method2",Integer.class);
        method2.invoke(userClass.newInstance(),18);

运行结果:
在这里插入图片描述

如上代码,getMethod方法中有两个参数,第一个参数为方法名,第二个参数为一个长度可变的参数,它的含义是此方法的多个参数按顺序排列的类对象,假设你的方法为xxxGet(Integer x,String y,Double z),那么你的第二个参数的传参形式为:Integer.class,String.class,Double.calss或者直接使用一个数组new Object[]{Integer.class,String.class,Double.calss},然后真正的调用为invoke()方法,此方法也有两个参数,第一个参数为方法所在的类的实例,第二个为长度可变的参数,他和上面的参数类型相互呼应,以xxxGet(Integer x,String y,Double z)为例,第二个参数你可以写成2,“Roman”,3或者new Object[]{2,“Roman”,3};

2.4)getMethod()和getDeclaredMethods()的区别

getMethod()获取自身能用所有的public公共方法。1.类本身的public 2.继承父类的public 3.实现接口的public;getDeclaredMethod()获取类自身声明的所有方法,包含public、protected和private方法。

/**
         * getMethod() 和 getDeclaredMethods()的区别
         *
         */
        Method [] methods = userClass.getMethods();
        for(Method item : methods){
            System.out.println("--method-- " + item.getName());
        }
        Method [] methodsDec = userClass.getDeclaredMethods();
        for(Method item : methodsDec){
            System.out.println("--methodDec-- " + item.getName());
        }

运行结果:
在这里插入图片描述
在这里插入图片描述

可以看到
1.getMethod()并没有获取到私有方法method3
2.getMethod()获取到了父类的公共方法,因此比getDeclaredMethod()要多

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

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

相关文章

react学习3 生命周期

componentDidMount()与render()一个级别的,在组件挂载完成之后调用 卸载组件:REACTDOM.unmountComponentAtNode() componentWillUnmount() 组件马上被卸载的时候 老生命周期: 新的生命周期: 废弃了(加上Unsate_还是…

Python3安装pyhanlp最佳解决方法

1、Hanlp介绍 Hanlp是一款中文自然语言处理工具。Hanlp支持多种自然语言处理任务,包括分词、词性标注、命名实体识别、依存句法分析、情感分析、文本分类等。其主要优点包括: 高准确率:Hanlp采用了基于神经网络的分词方法,有效提…

关于字符集

字符集 编码与解码 计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。反之,将存储在计算机中的二进制数…

【老王读SpringMVC-7】Controller method 的异常返回值处理

通过前面分析 Controller method的执行过程,我们知道, handler method 的执行是通过调用 ServletInvocableHandlerMethod#invokeAndHandle()。 执行过程中的异常全部会往上抛出,然后由 DispatcherServlet 来处理。 DispatcherServlet 会调用 …

MATLAB第十章_图像处理算法

目录 图像处理算法 图像处理基础 图像处理函数 默认显示方式 添加颜色条 显示多帧图像 显示动画 三维材质图像 图像的直方图 灰度变换 均衡直方图 图像处理应用 图像增强 图像重建 图像变换 图像压缩 图像分割 图像边缘检测 图像识别 图像处理算法 图像处理…

化繁为简,在线表单工具值得一试!

在办公职场中,经常听到不少人抱怨:表单制作效率低、数据整理麻烦等,这个时候不少办公职员是多么希望能有一整套完善的表单制作工具来满足办公需求,快速提升办公协作效率。不要着急,如今是产业分工新时代,在…

Linux终端环境下的浏览器Lynx和Carbonyl 的基本使用方法

一、Carbonyl 是基于Chromium开发的运行于终端下的现代版浏览器,比Lynx的功能更好,目前尚在滚动开发过程中,但也基本可以用了。 1. 2安装非常简单,下载Binaries,Docker,nmp install, 都可以。 注意&#…

智能电表怎么实现远程抄表

智能电表是一种新型的电表,它可以实现远程抄表的功能。智能电表的远程抄表是通过无线网络或有线网络来实现的,这使得抄表变得更加方便和快捷。本文将介绍智能电表如何实现远程抄表的技术原理和实现方法。 一、技术原理 智能电表的远程抄表是通过将电表与…

定了 香港新政6月1日生效 散户交易加密货币正式合法化!

如今,香港虚拟资产交易的各项准备工作已准备就绪。5月23日,香港证监会(SFC)详细介绍了各界参与虚拟资产交易的咨询总结文件,宣布《适用于虚拟资产交易平台营运者的指引》将于2023年6月1日生效。 SFC行政总裁梁凤仪表示…

2023 最全 Java 面试八股(涵盖所有 Java 核心面试知识点),立刻收藏

2022 已成为过去式,不论这一年好与坏,我们都需要抓住新一年的机会,跳槽涨薪,还是学习提升!先给自己定一个小目标,然后再朝着目标去努力就完事儿了!为了帮大家节约时间,给大家搞来了 …

2023 华为 Datacom-HCIE 题库 02--含解析

单选题 1.[试题编号:189785] (单选题)如图所示,VTEP1上在BD20域内开启了ARP广播抑制功能,并且VTEP1通过 BGP EVPN路由学习到了PC2的ARP信息,则PC1发送的针对PC2的ARP请求,VIEP1在转发给VIEP2时…

SpringCloud(23):Sentinel对Spring Cloud Gateway的支持

代码地址:https://download.csdn.net/download/u013938578/87767363 从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流: route 维度:即在 Spring 配置文件中配置的路…

ChatGPT 入门教程||ChatGPT 应用场景1:让AI回答问题||ChatGPT应用场景2:基于已有的示例回答

ChatGPT 应用场景1:让AI回答问题 这个场景应该是使用 AI 产品最常见的方法。以 ChatGPT 为例,一般就是你提一个问题,ChatGPT 会给你答案,比如像这样: 在这个场景下,prompt 只要满足前面提到的基本原则&am…

通过opencv与神经网络对滑动验证码的一次深入学习

好久没写博客了,人到中年,有点儿犯懒。 从信息安全行业,又去了IT合规领域,与信息安全结合还是两手抓,两手都不硬。 由于工作原因,需要获取一个token来请求接口,奈何没有现成的接口&#xff0c…

记一次Android页面卡顿排查总结

背景:更新完gosdk(端上的主要逻辑在go层完成)后,冷启动时首页明显会卡一下 问题排查: 1、通过在application onCreate()中设置getMainLooper().setMessageLogging(new LxLogPainter());来查看耗时的日志,…

cfssl使用方法重新整理说明

下载安装: #下载cfssl、cfssl-json、cfssl-certinfo文件 wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/bin/cfssl wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/bin/cfssljson wget https://pkg.cfssl.org/R1.2/cfssl-certinfo…

低代码开发:构建企业数字化生态系统的秘密武器!

目前,我们正处于数字化时代,而企业数字化早已是大势所趋,也是因为企业数字化转型是提高企业效率与竞争力的必经之路。 发展背景 近年来,伴随着人工智能、大数据分析技术、云计算等领域的迅速发展,不少企业开始正视数字…

【How to Design Translation Prompts for ChatGPT: An Empirical Study 论文略读】

How to Design Translation Prompts for ChatGPT: An Empirical Study 论文略读 INFORMATIONAbstract1 Introduction2 Background3 Experiments3.1 Prompt Design3.2 Experimental Setup3.2.1 Datasets3.2.2 Baselines and Evaluation Metrics 3.3 Multilingual Translation3.4…

接入支付宝沙箱环境

1、这里有几个重要数据要拿到,一个是支付宝的公钥和私钥,一个是支付的网关,和支付的APPID。这几个数据是要写到代码中的 官方手册:文档地址 1.1 配置沙箱应用环境 https://openhome.alipay.com/develop/sandbox/app 1.2 配置接口…

Git忽略文件的几种方法,以及.gitignore文件的忽略规则

Git忽略文件的几种方法,以及.gitignore文件的忽略规则 .gitignore文件定义Git全局的.gitignore文件Git 忽略规则Git忽略规则的优先级.gitignore文件忽略规则常用匹配示例: 关于.gitignore规则不生效的问题 不忽略没有后缀名的文件搜索电脑里没有后缀的文…