Java 反射机制

本文详细介绍了Java反射机制,包括其概念、API的使用,如Class类、Constructor、Method和Field对象的创建与操作。通过反射,可以在运行时动态获取类信息、访问构造方法、执行方法和成员变量,实现代码的灵活性和扩展性。同时,文章也讨论了反射的优缺点,以及如何通过反射创建对象、调用方法和访问成员变量的具体步骤。
摘要由CSDN通过智能技术生成


一、Java反射机制是什么?

编译期和运行期:

编译期是指把源码交给编译器编译成计算机可以执行的文件的过程。在Java中也就是把Java代码编成class文件的过程。编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而是把代码当成文本进行操作,比如检查操作。
运行期是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来。


Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。简单来说,反射机制指的是程序在运行时能够获取自身的信息。在Java中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。


Java反射机制在服务端,往往需要根据客户的请求,动态调用某一个对象的特定方法。此外,在ORM中间件的实现中,运用Java反射机制可以读取任意一个JavaBean的所有属性,或者给这些属性赋值。在这里插入图片描述


Java的反射机制主要提供了以下功能,这些功能都位于 java.lang.reflect 包。

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

Java 反射机制的优缺点
优点:

  • 能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。
  • 与 Java 动态编译相结合,可以实现无比强大的功能。
  • 对于 Java 这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。

缺点:

  • 反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;
  • 反射调用方法时可以忽略权限检查,获取这个类的私有方法和属性,因此可能会破坏类的封装性而导致安全问题。

二、Java反射机制API

实现Java反射机制的类都位于java.lang.reflect包中,java.lang.Class类是Java反射机制API中的核心类。

1.java.lang.Class 类

java.lang.Class类是实现反射的关键所在,Class类的一个实例表示Java的一种数据类型,包括类、接口、枚举、注解(Annotation)、数组、基本数据类型和void。Class没有公有的构造方法,Class实例是由JVM在类加载时自动创建的。
获得Class实例:

// 1. 通过类型class静态变量
Class clz1 = String.class;
String str = "Hello";
// 2. 通过对象的getClass()方法
Class clz2 = str.getClass();

2.java.lang.reflect 包

java.lang.reflect 包提供了反射用到的类:

  • Constructor类:提供类的构造方法信息。
  • Field类:提供类或接口中成员变量信息。
  • Method类:提供类或接口成员方法信息。
  • Array类:提供了动态创建和访问Java数组的方法。
  • Modifier类:提供类和成员访问访问修饰符信息。

反射:运行时类信息
类 Class 支持反射的概念,java.lang.reflect库中包含类Field、Method和Constructor(每一个都实现了Member接口)。这些类型的对象由JVM在运行时创建,以表示未知类中的对应成员。然后,可以使用Constructor创建新对象,get( )和set( )方法读取和修改与Field对象关联的字段,invoke( )方法调用与Method对象关联的方法。
此外,还可以调用便利方法getFields( )、getMethods( )、getConstructors( )等,以返回表示字段、方法和构造函数的对象数组。因此,匿名对象的类信息可以在运行时完全确定,编译时不需要知道任何信息。


三、Java通过反射访问构造方法

为了能够动态获取对象构造方法的信息,首先需要通过下列方法之一创建一个Constructor类型的对象或者数组。

  • getConstructors( )
  • getConstructor( Class<?> …paramerTypes )
  • getDeclaredConstructors( )
  • getDeclaredConstructor( Class<?> …parameterTypes)

**如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。**例如,访问一个入口参数类型依次为 int 和 String 类型的构造方法,下面的两种方式均可以实现。

objectClass.getDeclaredConstructor(int.class,String.class);
objectClass.getDeclaredConstructor(new Class[]{int.class,String.class});

创建的每个 Constructor 对象表示一个构造方法,然后利用 Constructor 对象的方法操作构造方法。Constructor 类的常用方法:
在这里插入图片描述


四、Java通过反射执行方法(获取方法)

动态获取一个对象方法的信息,需要通过下列方法之一创建一个Method类型的对象或者数组。

  • getMethod( )
  • getMethods(String name,Class<?> …parameterTypes)
  • getDeclaredMethods()
  • getDeclaredMethods(String name,Class<?>…parameterTypes)

如果是访问指定的构造方法,需要根据该方法的入口参数的类型来访问。例如,访问一个名称为 max,入口参数类型依次为 int 和 String 类型的方法。下面的两种方式均可以实现:

objectClass.getDeclaredConstructor(“max”,int.class,String.class);
objectClass.getDeclaredConstructor(“max”,new Class[]{int.class,String.class});

Method 类的常用方法:
在这里插入图片描述


五、通过反射访问成员变量

通过下列方法访问成员变量时将返回Field类型的对象或数组。

  • getFields()
  • getField(String name)
  • getDeclaredFields()
  • getDeclaredField(String name)

上述方法返回的Field对象代表一个成员变量。例如,要访问一个名称为 price 的成员变量,示例代码如下:

object.getDeciaredField(“price”);

Field 类的常用方法:
在这里插入图片描述


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值