Java:反射 reflection ( 概念+相关类+使用方法)

文章目录

  • 一、反射(reflection)
    • 1.概念
            • 优点:
            • 缺点
    • 2.反射的相关类
      • 1.Class类
          • 1.**反射机制的起源**
          • 2.获得类相关的方法
          • 3.获得类中属性的相关方法
          • 4.获得类中注解相关的方法
          • 5.获得类中构造器相关的方法
          • 6.获得类中方法相关的方法
      • 2.获取Class对象的三种方法:
            • 1.使用 Class.forName("类的全路径名");
            • 2.使用 .class 方法。
            • 3.使用类对象的 getClass() 方法

一、反射(reflection)


1.概念

  • Java的反射机制是 在运行状态中,可以知道任何一个类的所有属性和方法
  • 可以调用任意一个对象的任意方法和属性
  • 拿到之后就可以进行修改
  • 反射就是动态获取信息、动态调用对象方法的一种功能
优点:
  • 可以获得一个类的所有属性和方法,进行调用、修改。反射运用在很多主流框架
  • 提高灵活性和扩展性,降低耦合
缺点
  • 导致效率降低
  • 可读性差,不好维护

2.反射的相关类

类名用途
Class类代表类的实体,在运行的Java程序中表示类的接口
Field类代表类的成员变量、类的属性
Method类代表类的方法
Constructor类代表类的构造方法

1.Class类

1.反射机制的起源
  • Java文件被编译后会生成.class文件
  • .class文件会被JVM解析成一个对象:java.long.Class
  • 在运行时,每个java文件最终会变成Class类对象的一个实例
  • 通过反射,获取、添加、修改这个类的属性和方法,成为一个动态的类
2.获得类相关的方法
方法用途
getClassLoader()获得类的加载器
getDeclaredClasses()返回一个数组,数组中包含该类中所有类和接口类的对象(包括私有的)
forName(String className)根据类名返回类的对象
newInstance()创建类的实例
getName()获得类的完整路径名字

在这里插入图片描述

  • 获取Class对象,通过newInstans方法创建类的实例
    public static void reflectNewInstance() {        Class<?> classStudent = null;try {classStudent = Class.forName("reflect.Student");//获取Class对象Student student = (Student) classStudent.newInstance();//强转,向下转向System.out.println(student);//Student{name='小明', age=20}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}  }
  • newInstans方法会抛出 InstantiationException, IllegalAccessException两个异常
  • 方法的返回值是T,被擦除成了Object,所以要进行强制类型转换
3.获得类中属性的相关方法

(以下方法返回值为Field相关)

方法用途
getField(String name)获得某个公有的属性对象
getFields()获得所有公有的属性对象
getDeclaredField(String name)获得某个属性对象
getDeclaredFields()获得所有属性对象
    // 反射私有属性public static void reflectPrivateField() {Class<?> classStudent = null;try {classStudent = Class.forName("reflect.Student");Field field = classStudent.getDeclaredField("name");field.setAccessible(true);//进行确定Student student = (Student) classStudent.newInstance();field.set(student,"王大锤");System.out.println(student);//Student{name='王大锤', age=20}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchFieldException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}
4.获得类中注解相关的方法
方法用途
getAnnotation(Class annotationClass)返回该类中与参数类型匹配的公有注解对象
getAnnotations()返回该类所有的公有注解对象
getDeclaredAnnotation(Class annotationClass)返回该类中与参数类型匹配的所有注解对象
getDeclaredAnnotations()返回该类所有的注解对象
5.获得类中构造器相关的方法

(以下方法返回值为Constructor相关)

方法用途
getConstructor(Class…<?> parameterTypes)获得该类中与参数类型匹配的公有构造方法
getConstructors()获得该类的所有公有构造方法
getDeclaredConstructor(Class…<?> parameterTypes)获得该类中与参数类型匹配的构造方法
getDeclaredConstructors()获得该类所有构造方法

在这里插入图片描述

  • 同理,获得该类中与参数类型匹配的构造方法
  • 要传入对应构造方法中,参数类型的class对象
		  classStudent = Class.forName("reflect.Student");//获取Class对象Constructor<?> constructor = classStudent.getDeclaredConstructor(String.class, int.class);//获得该类中与参数类型匹配的构造方法

在这里插入图片描述

  • 这里是 constructor的newInstance()方法,传入初始化的参数列表
  • 添加对应的异常,并且进行强转
  • 因为是私有的构造方法,所以要调用setAccessible(true)方法,填上true 体现安全性(需要确认)
  • 反射打破了封装机制
 public static void reflectPrivateConstructor()   {      Class<?> classStudent = null;try {classStudent = Class.forName("reflect.Student");//获取Class对象Constructor<?> constructor = classStudent.getDeclaredConstructor(String.class, int.class);//获得该类中与参数类型匹配的构造方法constructor.setAccessible(true);Student student = (Student) constructor.newInstance("小红", 18);//这里是 constructor的newInstance()方法System.out.println(student);//Student{name='小红', age=18}} catch (NoSuchMethodException e) {e.printStackTrace();} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}
}
6.获得类中方法相关的方法

(以下方法返回值为Method相关)

方法用途
getMethod(String name, Class…<?> parameterTypes)获得该类某个公有的方法
getMethods()获得该类所有公有的方法
getDeclaredMethod(String name, Class…<?> parameterTypes)获得该类某个方法
getDeclaredMethods()获得该类所有方法
    // 反射私有方法public static void reflectPrivateMethod() {Class<?> classStudent = null;try {classStudent = Class.forName("reflect.Student");Method method = classStudent.getDeclaredMethod("function", String.class);method.setAccessible(true);Student student = (Student) classStudent.newInstance();method.invoke(student,"不要吃");//不要吃} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}}

2.获取Class对象的三种方法:

1.使用 Class.forName(“类的全路径名”);

静态方法,前提是知道类的全路径名。

在这里插入图片描述

        Class<?> C1 = null;try {C1 = Class.forName("reflect.Student");} catch (ClassNotFoundException e) {e.printStackTrace();}
  • forName会抛出 ClassNotFoundException异常, ClassNotFoundException继承于Exception
  • 所以默认是一个受查异常(编译时异常),需要进行处理(JVM/手动抓取)
2.使用 .class 方法。
 Class<Student> C2 = Student.class;

仅适合在编译前就已经明确要操作的 Class

3.使用类对象的 getClass() 方法
        Student student = new Student();Class<? extends Student> C3 = student.getClass();System.out.println(C1 == C2);//trueSystem.out.println(C1 == C3);//true
  • Class对象只存在一个

点击移步博客主页,欢迎光临~

偷cyk的图

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

报表生成器FastReport .Net用户指南:脚本示例

FastReport的报表生成器&#xff08;无论VCL平台还是.NET平台&#xff09;&#xff0c;跨平台的多语言脚本引擎FastScript&#xff0c;桌面OLAP FastCube&#xff0c;如今都被世界各地的开发者所认可&#xff0c;这些名字被等价于“速度”、“可靠”和“品质”,在美国&#xff…

Phoenix伪分布安装

引言 Phoenix是构建在HBase上的一个SQL层&#xff0c;能让我们用标准的JDBC APIs而不是HBase客户端APIs来创建表&#xff0c;插入数据和对HBase数据进行查询。Phoenix完全使用Java编写&#xff0c;作为HBase内嵌的JDBC驱动。Phoenix查询引擎会将SQL查询转换为一个或多个HBase扫…

怎么看电脑是32位还是64位?

不同的操作系统会有不同的操作功能&#xff0c;适应不同的软件。最近有网友想了解自己的电脑是几位数的&#xff0c;相信很多小伙伴也有同样的疑惑吧&#xff0c;搞不清楚系统是32位还是64位。其实&#xff0c;我们通过计算机即可查看&#xff0c;操作方法很简单&#xff0c;接…

如何开始定制你自己的大型语言模型

2023年的大型语言模型领域经历了许多快速的发展和创新&#xff0c;发展出了更大的模型规模并且获得了更好的性能&#xff0c;那么我们普通用户是否可以定制我们需要的大型语言模型呢&#xff1f; 首先你需要有硬件的资源&#xff0c;对于硬件来说有2个路径可以选。高性能和低性…

Anaconda的GEE环境中安装torch库

打开Anaconda&#xff0c;点击运行&#xff0c;打开terminal 输入pip install torch 而且由于anaconda中自己配置好了镜像源&#xff0c;在pip时自动使用清华镜像源

OpenAI文本转视频模型Sora运行成本高昂;抖音打击利用AI生成虚拟人物违规行为

&#x1f989; AI新闻 &#x1f680; OpenAI文本转视频模型Sora运行成本高昂 摘要&#xff1a;市场调查机构Factorial Funds最新报告显示&#xff0c;OpenAI旗下文本转视频模型Sora在峰值期需要达到72万片英伟达H100 AI加速卡&#xff0c;相当于成本约216亿美元。每片H100的功…

java解决跨域问题

浏览器js在访问服务器中的资源时&#xff0c;会出现同一页面或者不同域名(协议&#xff0c;IP&#xff0c;端口)不可访问 例如:file://d://test.html页面(file协议)中通过ajax访问服务器api.test.com的接口(http协议)&#xff0c;由于协议不同&#xff0c;此时会出现浏览器访问…

U盘未格式化?数据恢复大揭秘!

在日常办公和生活中&#xff0c;U盘已成为我们不可或缺的数据存储工具。然而&#xff0c;有时我们会遇到这样一个令人头疼的问题&#xff1a;原本正常使用的U盘&#xff0c;突然提示“未格式化”&#xff0c;里面的文件似乎都消失不见了。面对这种情况&#xff0c;很多人会感到…

力扣热门算法题 124. 二叉树中的最大路径和,125. 验证回文串,127. 单词接龙

124. 二叉树中的最大路径和&#xff0c;125. 验证回文串&#xff0c;127. 单词接龙&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.26 可通过leetcode所有测试用例。 目录 124. 二叉树中的最大路径和 解题思路 完整代码 Pyt…

Ubuntu安装教程——Desktop版本(细致入微的操作)

目录 前言 一、安装Ubuntu桌面版操作系统 二、UbuntuLive版安装 1.语言选择 2.键盘布局 3.版本选择 4.网络配置 5.代理配置 6.镜像地址 7.磁盘划分 8.设置用户信息 9.ssh 10.选择软件包 11.安装界面 12.基础配置 12.1root用户 12.2时区 12.3包管理工具 12…

tcp和udp的区别是什么

tcp和udp的区别是什么 TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;是互联网协议族中的两个重要传输层协议。 一、工作原理 1.TCP工作原理&#xff1a; TCP是一种面向连接的协议&#xff0c;通过三次握手建立可靠的连接。发送端将数…

三度荣膺!ATFX再次摘得MT4经纪商顶级大奖,实力铸就荣耀

阳春三月&#xff0c;荣誉时刻再次如约而至。日前&#xff0c;英国《全球品牌杂志》主办的Global Brand Award Winners 2024公布获奖名单&#xff0c;ATFX作为历届榜单的常客&#xff0c;不负众望&#xff0c;继2021年、2023年的辉煌之后&#xff0c;今年再度双喜临门&#xff…