java 编程中的反射机制_浅析Java中的反射机制原理

java 编程中的反射机制_浅析Java中的反射机制原理反射反射,程序员的快乐!Java中反射机制使用的还是比较广泛的,系统的灵活性、可扩展性大都都是通过反射等方式来加载外部插件,使得系统与插件解耦的同时,增加了功能。但是很多人都只是会用,却是不知道它的实现机制,今天就由我来带大家揭开反射机制的神秘面纱。Java中是用Class.forName(classname)来反射类。packagecom.java.reflecttest;importcom…

大家好,欢迎来到IT知识分享网。

反射反射,程序员的快乐!

Java中反射机制使用的还是比较广泛的,系统的灵活性、可扩展性大都都是通过反射等方式来加载外部插件,使得系统与插件解耦的同时,增加了功能。但是很多人都只是会用,却是不知道它的实现机制,今天就由我来带大家揭开反射机制的神秘面纱。

Java中是用Class.forName(classname)来反射类。

package com.java.reflecttest;

import com.java.dbtest.DBTest;

/**

* Java反射机制测试

* @author Longxuan

*

*/

public class ReflectTest {

/**

* 测试反射类

*/

public static void refTest(){

String className = “com.java.dbtest.TestConnection”;

DBTest dbTest = null;

try {

//通过反射机制,使用类装载器,装载该类

Class tc = Class.forName(className);

//输出反射得到的类

System.out.println(tc);

//创建该类的实例,转化为接口

dbTest =(DBTest)tc.newInstance();

//通过接口,调用该类的方法

dbTest.SelectUser();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

public static void main(String[] args){

refTest();

}

}

通过main函数的调试,已经通过,结果如图:

8e87170a23251c3b78519adba68ecd88.png       

3bb8bb9d3bcdece136a230ef4d18dc31.png

经过调试,查资料,结合自己的推测和理解,似乎是明白了一些。现与大家分享讨论。

先说执行过程:

Class.forName(classname)方法,实际上是调用了Class类中的 Class.forName(classname, true, currentLoader)方法。参数:name – 所需类的完全限定名;initialize – 是否必须初始化类;loader – 用于加载类的类加载器。currentLoader则是通过调用ClassLoader.getCallerClassLoader()获取当前类加载器的。类要想使用,必须用类加载器加载,所以需要加载器。反射机制,不是每次都去重新反射,而是提供了cache,每次都会需要类加载器去自己的cache中查找,如果可以查到,则直接返回该类。

有意思的是java的类加载器也有些门道。它分为BootStrap Class Loader(引导类加载器),Extensions Class Loader (扩展类加载器),App ClassLoader(或System Class Loader),当然少不了Custom ClassLoader(用户自定义类加载器)。其加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。类加载器的详细介绍会在接下来的博文中较深入的分析,欢迎期待。

在forName方法中,调用了ClassLoader.loadClass方法来完成类的反射。根据类加载器的特殊性,结合我的调试过程,画了一个简单的流程图,

5f893cc02418fe7b95eaba561e57d57b.png

我的这幅图简单的说明了类加载器的类加载过程。先检查自己是否已经加载过该类,如果加载过,则直接返回该类,若没有则调用父类的loadClass方法,如果父类中没有,则执行findClass方法去尝试加载此类,也就是我们通常所理解的片面的”反射”了。这个过程主要通过ClassLoader.defineClass方法来完成。defineClass 方法将一个字节数组转换为 Class 类的实例(任何类的对象都是Class类的对象)。这种新定义的类的实例需要使用 Class.newInstance 来创建,而不能使用new来实例化。

为什么说“任何类的对象都是Class类的对象”呢?在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类(.java文件),编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。

其实说的简单通俗一点,就是在运行期间,如果我们要产生某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。如果没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已被加载到内存,就可以用它来产生该类型的所有对象。

以上内容是我经过调试、查java Api和网上资料,结合自己的理解,与大家分享讨论的,如果有错,欢迎大家指正,我们共同进步。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/21781.html

(0)
上一篇 2024-01-15 14:33
下一篇 2024-01-15 17:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信