java反射API

news2024/11/25 17:22:27

反射

  • 什么是Java的动态机制
  • 什么是反射机制
  • 什么是Class类
    • Class提供了诸多的get方法
  • 反射机制实例化对象
    • Class提供了一个方法
  • Constructor类
    • 指定构造器实例化对象
  • Method类
    • 获取一个类中的所有方法
      • Class类提供了对应的方法
    • 获取本类自定义的所有方法
      • Class类提供了对应的方法
    • 获取表示的方法中的相关信息
      • Class类提供了对应的方法
    • 利用反射机制调用方法
      • Class类提供了对应的方法
    • 暴力反射
      • 反射机制访问类的私有成员的方法
    • 反射机制操作属性
      • Class类提供了对应的方法
    • 通过类对象获取类加载路径和当前类路径
      • Class类提供了对应的方法

什么是Java的动态机制

什么是反射机制

反射是java的动态机制,允许程序在[运行期间]再确定对象实例化,方法调用,属性操作等
反射可以提高代码的灵活度和可扩展性,但是运行效率较慢,开销较大,避免过度使用

什么是Class类

  • java.lang.Class类是Java反射机制的基础
  • Class的每一个实例用于表示JVM中加载的一个类
  • JVM中每个被加载的类都有且只有一个Class的实例
  • Class类的构造器是私有的,开发者不能主动实例化Class类的对象
  • Class类的对象仅能由JVM创建

类对象:
Class类的实例

  • JVM加载一个类的字节码文件同时会实例化一个Class的实例用来记录加载的类的信息.
    那么这个Class的实例就可以反映出加载的类的相关信息(类名,包信息,构造器,方法,属性等)
    从而在程序运行期间供我们了解一个类的内容以便进行操作.

  • 在JVM内部,每个被加载的类都有且只有一个Class的实例.

  • 反射的第一步是获取一个类的类对象(Class的实例)

获取方式一:

  • 类名.class
    例如:
    Class c1 = String.class;//获取String的类对象
    Class c2 = int.class;//获取int(基本类型)的类对象.
    注意:基本类型获取类对象只有这一种方式

获取方式二:

  • Class.forName(String className)
    通过指定一个类的完全限定名来获取一个类的类对象
    例如:
    Class c1 = Class.forName(“java.lang.String”);
    Class c2 = Class.forName(“java.util.ArrayList”);

Class提供了诸多的get方法

用于获取其表示的类的相关信息

  • getName()
  • getSimpleName()
  • getPackage()
  • getPackage().getName()

反射机制实例化对象

Class提供了一个方法

  • Object newInstance()
    类必须有一个无参数的构造器,否则就需要传入构造器对应的参数
    类的构造器的访问权限需要足够,通常设置为public
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        Person person = new Person();
        System.out.println(person);
        Class cls = Class.forName("reflect.Person");
        System.out.println(cls.newInstance());

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入类名");
        Class clsName = Class.forName(scanner.nextLine());
        System.out.println(clsName.newInstance());

    }

Constructor类

  • Constructor类是反射对象之一,它的每一个实例用于表示一个构造器
  • 使用无参构造器,等效与Class中的newInstance()
    如果构造器抛出特定异常此方式可对应抛出该异常

指定构造器实例化对象

public class Person {
    private String name = "张三";
    private int age = 22;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
public static void main(String[] args) throws InvocationTargetException, 
InstantiationException, IllegalAccessException, NoSuchMethodException, 
ClassNotFoundException {
        Person person = new Person("李四",22);
        System.out.println(person);

        Class cls = Class.forName("reflect.Person");

        Constructor constructor = cls.getConstructor(String.class,int.class);
        System.out.println(constructor.newInstance("王五",36));


        Constructor constructor1 = cls.getConstructor();
        System.out.println(constructor1.newInstance());
    }

Method类

Method类是反射对象之一,它的每一个实例用于表示一个方法
通过Method对象我们可以得知该方法的相关信息(方法名,参数列表,返回值,访问修饰符等)
还可以通过Method对象调用该方法

获取一个类中的所有方法

Class类提供了对应的方法

  • Method[] getMethods()
public class Person {
    private String name = "张三";
    private int age = 22;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public void sayHello(){
        System.out.println();
    }
    public void sayHi(){
        System.out.println();
    }
    public void doSome(){
        System.out.println();
    }
    public void sleep(){
        System.out.println();
    }
    public void watchTV(){
        System.out.println();
    }
    public void study(){
        System.out.println();
    }
    public void playGame(){
        System.out.println();
    }
    public void sing(){
        System.out.println();
    }
    public void say(String info){
        System.out.println(name+":"+info);
    }
    public void say(String info,int count){
        for (int i=0;i<count;i++){
            System.out.println(name+":"+info);
        }
    }
    private void hehe(){
        System.out.println("我是Person的私有方法hehe!!");
    }
}
public static void main(String[] args) throws ClassNotFoundException {
        Scanner scanner = new Scanner(System.in);
        Class cls = Class.forName(scanner.nextLine());

        Method[] methods = cls.getMethods();
        System.out.println("一共:" +methods.length+ "个方法");

        for(Method method : methods){
            System.out.println(method.getName());
        }
    }

获取本类自定义的所有方法

Class类提供了对应的方法

  • Method[] getDeclaredMethods()
    不含超类继承的方法
public static void main(String[] args) throws ClassNotFoundException {
        Class cls = Class.forName("reflect.Person");
        Method[] methods = cls.getDeclaredMethods();
        for(Method method : methods){
            System.out.println(method.getName());
        }
    }

请添加图片描述

获取表示的方法中的相关信息

Class类提供了对应的方法

  • getDeclaredMethod(String)
  • getDeclaredMethod(String, in)
    获取有参方法时,getDeclaredMethod的第一个参数为方法名,从第二个参数开始为获取方法的参数列表
  • getParameterCount()
    获取当前方法的参数个数
  • getModifiers()
    获取当前方法的访问修饰符
    Method对象表示一个方法,其提供了一组可以获取表示的方法中的相关信息
public static void main(String[] args) throws NoSuchMethodException, 
ClassNotFoundException {
        Class cls = Class.forName("reflect.Person");
        Method method = cls.getDeclaredMethod("say", String.class, int.class);

        System.out.println("方法名" +method.getName());
        System.out.println("参数个数" +method.getParameterCount());

        switch (method.getModifiers()){
            case Modifier.PUBLIC:
                System.out.println("是一个公开方法");
                break;
            case Modifier.PRIVATE:
                System.out.println("是一个私有方法");
                break;
            case Modifier.PROTECTED:
                System.out.println("是一个受保护方法");
        }

    }

利用反射机制调用方法

Class类提供了对应的方法

  • Object invoke(Object obj)
    无参调用
public static void main(String[] args) throws NoSuchMethodException, 
ClassNotFoundException, InstantiationException, IllegalAccessException, 
InvocationTargetException {
        Class cls = Class.forName("reflect.Person");
        Object obj = cls.newInstance();

        Method method = cls.getDeclaredMethod("doSome");
        method.invoke(obj);
	}
  • Object invoke(Object obj, Object…… args)
    确保传递给invoke方法的参数列表与所调用的方法的参数列表相匹配
    否则,将会抛出异常
public static void main(String[] args) throws Exception {
        Class cls = Class.forName("reflect.Person");
        Object obj = cls.newInstance();

        Method method = cls.getDeclaredMethod("say",String.class);
        method.invoke(obj, "hello");

        Method method1 = cls.getDeclaredMethod("say",String.class,int.class);
        method1.invoke(obj, "大家好",5);
    }

暴力反射

反射机制访问类的私有成员的方法

  • setAccessible(true)
    强行打开访问权限,访问私有方法
  • setAccessible(false)
    使用后,关闭私有成员的访问权限
public static void main(String[] args) throws Exception {
        Class cls = Class.forName("reflect.Person");
        Method method = cls.getDeclaredMethod("hehe");

        method.setAccessible(true);
        method.invoke(cls.newInstance());
        method.setAccessible(false);
    }

反射机制操作属性

Class类提供了对应的方法

  • Field getDeclaredField(String name)
    允许访问类的声明字段
    返回一个Field对象,表示指定类或接口声明的指定公共、受保护、默认(包)访问或私有字段
  • void set(Object obj, Object value)
    Field类的一个方法,obj是包含该字段的对象,value是要设置的新值
  • native Object get(Object obj)
public class Teacher {
    public String name;
    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                '}';
    }
}
public static void main(String[] args) throws ClassNotFoundException, 
InstantiationException, IllegalAccessException, NoSuchFieldException {
        Class cls = Class.forName("reflect.Teacher");
        Object object = cls.newInstance();

        cls.getDeclaredField("name").set(object, "Bloom");
        System.out.println(object);
    }

通过类对象获取类加载路径和当前类路径

Class类提供了对应的方法

  • getClassLoader()
    返回该类的类加载器,它是用来加载类文件的对象
  • getResource(“.”)
    获取资源路径的方法,它从当前类的类加载器中查找资源
    "."代表当前目录,这表示获取当前目录下的所有资源
  • toURI()
    将路径转换为统一资源标识符(URI),它可以唯一地识别任何资源,包括网络资源、文件系统资源等
public class ReflectDemo {
    public static void main(String[] args) throws URISyntaxException {
        File baseDir = new File(
        	//获取当前类的类加载器中的当前目录的资源路径,并将其转换为URI
          ReflectDemo.class.getClassLoader().getResource(".").toURI()
        );
        System.out.println(baseDir);

        File dir = new File(
        	//获取当前类的类加载器中的当前目录的资源路径,并将其转换为URI
           ReflectDemo.class.getResource(".").toURI()
        );
        System.out.println(dir);
    }
}

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

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

相关文章

第四章 应用SysML基本特性集的汽车示例 P2(断更)|系统建模语言SysML实用指南学习

仅供个人学习 使用试用版CSM很鸡肋&#xff0c;然后书中一些内容没有说明&#xff0c;自定义方面有点困难&#xff0c;第四章暂时停止 同时感觉画图的顺序也很随意&#xff1f;甚至需求图放在了后面&#xff0c;觉得很离谱。 准备跳过这一章节 汽车模型 续P1 序列图表示启…

SolidWorks2019安装教程(正版)

网盘资源附文末 一.简介 SolidWorks软件是世界上第一个基于Windows开发的三维CAD系统&#xff0c;由于技术创新符合CAD技术的发展潮流和趋势&#xff0c;SolidWorks公司于两年间成为CAD/CAM产业中获利最高的公司。良好的财务状况和用户支持使得SolidWorks每年都有数十乃至数百…

Es中出现unassigned shards问题解决

1、一般后台会报primary shard is not active Timeout: … 出现这种问题表示该索引是只读了&#xff0c;没办法进行shard及存储操作&#xff0c;优先排除是系统存储盘满了 2、通过监控工具查看(cerebro) 发现该索引shard 1 损坏 也可以通过命令进行查看 GET _cluster/allo…

阿里云短信服务接口返回: 只能向已回复授权信息的手机号发送

1、问题描述 在阿里云短信服务控制台&#xff0c;调用发送短信接口&#xff0c;报错&#xff1a;只能向已回复授权信息的手机号发送 2、问题分析 所使用的签名 是 测试or个人学习的 &#xff0c;所以会导致 有的手机号发送不出去验证码 3、解决 如果在测试阶段&#xff0c;非要…

Python小试牛刀:GUI(图形界面)实现计算器UI界面(一)

下一篇&#xff1a;Python小试牛刀&#xff1a;GUI&#xff08;图形界面&#xff09;实现计算器UI界面(二)-CSDN博客 Python GUI 是指 Python 图形用户界面库&#xff0c;它们可以帮助开发者创建在计算机上运行的图形用户界面&#xff08;GUI&#xff09;。下面是一些常用的 P…

64T存储松下mov和索尼mp4文件变0字节恢复案例

64T存储松下mov和索尼mp4文件变0字节恢复案例 小型入门的小NAS凭借超市的性价比在各行业中开始流行&#xff0c;可以通过搭配普通SATA硬盘就可以完成阵列上线&#xff0c;部署也很简单&#xff0c;一根网线就搞定。我们看一个影视公司64T小NAS存储比较奇怪的恢复案例。 故障存…

【JavaScript保姆级教程】for循环与for循环遍历数组

文章目录 前言一、for循环1.1 什么是For循环&#xff1f;1.2 For循环示例1. 打印偶数2. 倒序打印 1.3 For循环遍历数组 二、JavaScript中的循环嵌套1.1 while循环的嵌套示例1&#xff1a;乘法表 示例2&#xff1a;打印星号三角形2.2 for循环的嵌套示例1&#xff1a;二维数组遍历…

pwd - 显示当前工作目录的路径

pwd命令来自英文词组“print working directory”的缩写&#xff0c;其功能是用于显示当前工作目录的路径&#xff0c;即显示所在位置的绝对路径。 在实际工作中&#xff0c;我们经常会在不同目录之间进行切换&#xff0c;为了防止“迷路”&#xff0c;可以使用pwd命令快速查看…

linux二进制文件分析三大工具详解(ldd、readelf、nm)

介绍 测试代码源码、源码如下&#xff1a; #include <openssl/evp.h> #include <openssl/sm2.h> #include <openssl/rand.h> #include <iostream> #include <string>EVP_PKEY* generate_sm2_key_pair() {EVP_PKEY_CTX *ctx;EVP_PKEY *pkey nu…

Openssl数据安全传输平台019:外联接口类的封装以及动态库的制作 - Bug未解决,感觉不是代码的问题

文章目录 1 外联接口1.1 接口类的封装1.2 共享内存与配置文件 2 json格式配置文件的定义2.1 共享内存中存储的节点结构2.2 服务器端配置文件2.3 客户端配置文件2.4 改进配置文件 3 共享内存类修改4 将接口打包成库(静态/动态)4.1 相关的指令4.1.1 静态库4.1.2 动态库 4.2 外联接…

CONTAINING_RECORD宏

CONTAINING_RECORD宏的使用 已知类或结构体成员变量的地址&#xff0c;可以取得类或结构体对象的地址。 代码 #include <windows.h> #include <iostream>class MyClass { public:MyClass(){}virtual ~MyClass(){}public:int m_Value1;int m_Value2;int m_Value3; …

「图像 merge」无中生有制造数据

在进行一个新项目的时候&#xff0c;往往缺少一些真实数据&#xff0c;导致没办法进行模型训练&#xff0c;这时候就需要算法工程师自行制作一些数据了&#xff0c;比如这篇文章分享的 bag 目标检测&#xff0c;在检测区域没有真实的 bag数据 此时&#xff0c;就可以采用图像拼…

CHS零壹视频恢复程序换机加载扫描结果的方法

有些特殊情况下我们需要把当前机器上扫描的结果在另外一台机器上加载&#xff0c;这样可以避免多次扫描浪费时间。目前CHS零壹视频恢复程序监控版、专业版、高级版已经支持换机加载&#xff0c;下面这个教程演示了如何换机加载。 STEP1&#xff1a;选择扫描对象点击扫描->根…

4.3 抽象类和接口

思维导图: 4.3 抽象类和接口的笔记 4.3.1 抽象类 定义&#xff1a;当一个类需要定义成员方法描述其行为特征&#xff0c;但这些方法的实现方式无法确定时&#xff0c;Java提供了抽象类来满足这种需求。 特点&#xff1a; 抽象方法是使用abstract关键字修饰的方法&#xff0c;无…

Spring-创建非懒加载的单例Bean源码

补充&#xff1a;关于扫描的逻辑 /*** Scan the class path for candidate components.* param basePackage the package to check for annotated classes* return a corresponding Set of autodetected bean definitions*/ public Set<BeanDefinition> findCandidateCo…

【C++】无重复数字全排列(三种方法)和有重复数字全排列

文章目录 一、无重复数字排列1.1 题目描述1.2 用dfs方法1.2.1 思路分析1.2.2 代码编写 1.3 用交换法1.4 STL秒解1.4.1 所用函数1.4.2 代码编写 二、有重复数字排列2.1 思路分析2.2 代码编写 一、无重复数字排列 1.1 题目描述 把 1 ∼ n 1∼n 1∼n 这 n n n 个整数排成一行后…

Xray+awvs联动扫描

首先xray开启监听 xray_windows_amd64.exe webscan --listen 127.0.0.1:7777 --html-output xray-xxx.html --plugins sqldet,xxe,upload,brute-force,cmd-injection,struts,thinkphp 然后准备目标csv文件,每行一个url或ip然后加个逗号 接着awvs导入csv 对导进来的每个目…

【python海洋专题三十四】调用自己的colormore

点击蓝字&#xff0c;关注我们 ​ 【python海洋专题三十四】调用自己的colormore 有时候不想使用他们给好的&#xff0c;调用自己的colormore 使用素材 ncl的colormore。 格式文本格式&#xff01; 这样自己的colormore存入txt也可以使用了。 ​ 结果呈现 单个颜色调…

网络层协议【IP协议】

全文目录 基本概念IP协议IPv4 协议头格式&#xff1a;分片发送方进行分片&#xff1a;识别IP分片&#xff1a;组装IP分片&#xff1a; 网段划分DHCP技术IP分类 私有IP和共有IP1. 私有IP地址&#xff08;Private IP Address&#xff09;&#xff1a;2. 公网IP地址&#xff08;Pu…

接入文心一言实战(一):API申请与测试

大家好&#xff0c;我是豆小匠。 这期来介绍申请百度文心一言API的步骤。 第一步 注册百度智能云账号 网址&#xff1a;https://login.bce.baidu.com/new-reg?tplbceplat&fromportal 第二步&#xff1a;申请预置模型 网址&#xff1a;https://console.bce.baidu.com/qi…