反射(Reflection)是 Java中的一种机制,它是一种特殊的面向对象编程技术。在 Java中,反射可以分为静态反射和动态反射两种。静态反射是指在 Java程序运行时才进行的一种反射,它可以保证程序运行时不会出现内存泄漏等错误。下面将从静态和动态两个方面来进行介绍。首先介绍静态反射,接着介绍动态反射,最后通过实例来具体分析一下静态和动态的区别。 1.静态类型:定义在源文件中,不会随类的实例化而改变 2.动态类型:可以通过运行时动态加载和更新
-
1.静态反射
静态反射就是在 Java程序运行时才进行的一种反射,其主要工作原理如下: 在类加载时,应用程序就会生成一个 Class对象,这个 Class对象的属性和方法都是从源文件中继承来的。当应用程序对某个类进行调用时, Java解释器会从源文件中读取 Class对象的信息,然后在运行时对该类进行一次反射调用,从而使被调用的类恢复到以前的静态状态。整个过程非常简单,因此称之为静态反射。 在 Java中,如果类没有实例化,就会通过静态类型来表示该类的属性和方法。下面举个例子来说明一下静态类型是如何工作的: 这段代码首先定义了一个对象X,然后定义了一个对象Y。现在我们需要根据X和Y来创建一个新的对象T。为了创建T,我们必须使用类的 Class对象中提供的 Class接口。在类加载时,如果类没有实例化,那么就会先从源文件中读取 Class对象并将其实例化,然后再用类的 Class接口来访问这一对象。如果类没有实例化,那么在类加载时就会直接使用当前类中的属性和方法来创建T。 使用类加载时进行反射调用可以使应用程序中生成了一个新的类对象T。为了使这个T能够被运行时解析并加载到内存中,应用程序首先要获取一个 Class对象并将其实例化,然后再利用其属性和方法来调用T。 从上面的代码可以看出,静态类型是通过类加载时进行反射调用来生成的。由于动态类型是通过运行时动态加载和更新来实现的,因此当动态类型被调用时会与静态类型有一定差别: 通过上面两张图片可以看出两者在创建对象时都没有实例化,因此它们在创建对象时都是静态类型。
-
2.动态反射
动态反射是指在程序运行时,动态加载、动态更新对象的属性和方法,以满足程序中各种特殊需求。 1.通过反射实现加载 动态反射需要调用 Class. write ()方法来加载对象,具体过程如下: (1)创建一个对象实例,并且使用 this. pid= new Program (" myFuel"," length"," number"," arguments"); 2.更新 动态反射加载完成后,会在程序的运行阶段调用 Class. write ()方法来更新对象的属性和方法。注意,代码中可能会出现以下几种情况: 这是因为类中没有提供类的静态信息,如果类没有实现静态信息,就无法加载类中的属性和方法。 因为 Class. write ()方法需要在运行阶段才能加载所有的属性和方法。
-
3.静态和动态的区别
静态和动态都可以控制对象的类型,但是它们所能控制的内容不同。静态类型能够控制对象的类型,但是对象在运行时是不能改变它的类型的。当类被实例化时,对象的静态属性和方法都会被赋值给类的实例,并且继承了该对象对应的静态属性和方法。类被实例化后,这些属性和方法都会被删除,但是它们仍在运行时存在。 因此,在程序运行时如果需要获取这些属性和方法,就必须在程序运行时对其进行加载和更新。 如果类中需要添加新的属性和方法,并且不想使其对象被实例化时将其删除,可以使用动态类型。当需要将一个类进行实例化后再删除其对应的静态属性和方法时,可以使用动态类型。 例如:假设我们有一个名为 ArraySet的类,它的静态属性是 arraySet. setTimeout ()。在调用 ArraySet. setTimeout ()方法时会抛出一个异常:“OutOfMemoryError”,问题在于对象未被实例化时 ArraySet是无法被调用的。如果我们在程序运行时把对象进行实例化并将其属性和方法都添加到对应的静态属性和方法上,那么就可以在程序运行时对其进行加载和更新了。
-
4.实例分析
下面我们通过一个例子来分析一下静态反射和动态反射的区别: 上面例子中,我们定义了一个名为java.la ng. Class. Double的类,并在该类定义了一个 Class对象。在编译时, Java应用程序并没有对这个类进行任何修改,只是将其声明为 Class对象,并且将其实例化了。当类在运行时, Java应用程序会动态加载这个 Class对象并在类中定义一个新的变量来定义它。
-
常用的java反射代码如下:
-
1. 获取类对象
```
Class clazz = Class.forName("com.example.demo.User");
```
2. 获取类的构造方法
```
Constructor constructor = clazz.getConstructor(String.class, int.class);
```
3. 创建对象
```
Object obj = constructor.newInstance("Tom", 18);
```
4. 获取类的属性
```
Field field = clazz.getDeclaredField("name");
```
5. 设置属性值
```
field.setAccessible(true);
field.set(obj, "Jerry");
```
6. 获取类的方法
```
Method method = clazz.getDeclaredMethod("sayHello");
```
7. 调用方法
```
method.invoke(obj);
```