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

2024-03-28 13:20

本文主要是介绍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的图

这篇关于Java:反射 reflection ( 概念+相关类+使用方法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/855725

相关文章

python使用库爬取m3u8文件的示例

《python使用库爬取m3u8文件的示例》本文主要介绍了python使用库爬取m3u8文件的示例,可以使用requests、m3u8、ffmpeg等库,实现获取、解析、下载视频片段并合并等步骤,具有... 目录一、准备工作二、获取m3u8文件内容三、解析m3u8文件四、下载视频片段五、合并视频片段六、错误

Python中提取文件名扩展名的多种方法实现

《Python中提取文件名扩展名的多种方法实现》在Python编程中,经常会遇到需要从文件名中提取扩展名的场景,Python提供了多种方法来实现这一功能,不同方法适用于不同的场景和需求,包括os.pa... 目录技术背景实现步骤方法一:使用os.path.splitext方法二:使用pathlib模块方法三

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

spring中的ImportSelector接口示例详解

《spring中的ImportSelector接口示例详解》Spring的ImportSelector接口用于动态选择配置类,实现条件化和模块化配置,关键方法selectImports根据注解信息返回... 目录一、核心作用二、关键方法三、扩展功能四、使用示例五、工作原理六、应用场景七、自定义实现Impor

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项