首页 > 编程知识 正文

java的反射机制原理,通俗理解java反射

时间:2023-05-06 10:00:40 阅读:15426 作者:3523

一.原理

简而言之,反射机制是指程序可以在运行时获取自己的信息。 如果您知道类的名称/实例对象,则可以找到该类的所有方法和变量的信息(包括方法名称、变量名、方法、修饰符、类型和方法参数等所有信息)。 如果明确知道此类中某个方法名称参数的个数类型,也可以通过传递参数来执行该类中的该方法。 这就是反射。

虽然Java不是动态语言,但它有一个非常突出的动态机制: Reflection。 这样,在编译过程中就可以在运行时加载、探测和使用完全未知的classes。 也就是说,Java程序在运行时加载第一个识别名称的类,识别其完整结构(但methods定义除外),生成该对象实体,为其fields设置值,或调用methods 是“看穿类”的能力。

当然,在日常编程中很少使用反射,但在创建框架时会经常使用反射。 例如,虽然使用某个类进行操作,但由于该类是由用户在配置文件中配置的,因此必须首先阅读配置文件以获得该类的所有类名。 例如,使用test.Person,使用反射API进行操作。

二.优缺点

反射的优点当然体现在其动态性上,就是可以在运行时确定类型并绑定对象。 动态编译最大限度地发挥java的灵活性,体现多态性的应用,降低类间的耦合性。 总之,反射机制的优点是能够实现对象的动态创建和编译,特别是在J2EE的开发中,其灵活性尤为突出。 例如,大型软件不能一次完美地设计。 当发现此程序已编译并发布,并且需要更新某些功能时,用户无法卸载以前的版本并重新安装新版本。 如果是这样的话,这个软件肯定没人用。 如果是静态的,则必须重新编译整个程序才能实现功能更新,但反射机制允许在运行时动态创建,而无需卸载

和编译,可以实现这个功能。

其缺点是影响性能。 使用反射基本上是一种解释操作,我们可以告诉JVM我们想做什么,以及它是否满足我们的要求。 这样的操作总是比直接执行相同的操作慢。

三、利用反射实现类文件的逆编译

打包工具;

import Java.lang.reflect.constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import Java.lang.reflect.modifier;

import test.Person; //导入测试类文件

公共类反射测试{

publicstaticvoidmain (字符串[ ] args ) {

类c=null;

try {

//基于传递的类的全名创建Class对象。 注意必须是全名

c=class.forname(test.Person );

//获取数据包路径

system.out.println (package (c.get package ).getName ) ); n ';

//得到类修饰符

system.out.print (modifier.tostring ) c.getmodifiers ();

//得到类名

system.out.print (' class ' c.getsimplename ) );

//得到父类名

system.out.print (extends ' c.get super class ().getSimpleName ) );

//得到类实现的接口数组

Class[] inters=c.getInterfaces (;

if(Inters.Length0) {

system.out.print(implements );

for(intI=0; i inters.length; I ) {

system.out.print (inters [ I ].getsimplename ();

if(Iinters.Length-1 ) {

System.out.print (',');

}

}

}

system.out.println('{};

//获取类属性

打印机字段(c;

//获取类生成器

打印构造器(c;

获取//类方法

打印方法(c;

system.out.println('};

}catch(classnotfoundexceptione ) )

e .打印堆栈跟踪(;

>

}

}

private static void printConstructor(Class c){

Constructor[] cs = c.getConstructors();

for (int i = 0; i < cs.length; i++) {

System.out.println();

System.out.print("t");

// 得到整数形式构造函数修饰符,使用Modifier进行解码

System.out.print(Modifier.toString(cs[i].getModifiers()) + " ");

// 得到方法名

System.out.print(cs[i].getName() + "(");

// 得到方法参数数组

Class[] paras = cs[i].getParameterTypes();

for (int j = 0; j < paras.length; j++) {

System.out.print(paras[j].getSimpleName() + " arg" + j);

if (j < paras.length - 1) {

System.out.print(", ");

}

}

System.out.print(")");

System.out.println(" {");

System.out.println("tt\\方法体");

System.out.println("t}");

}

}

private static void printField(Class c) {

// 得到属性数组

Field[] fs = c.getDeclaredFields();

for (int i = 0; i < fs.length; i++) {

System.out.print("t");

// 得到整数形式属性修饰符,使用Modifier进行解码

System.out.print(Modifier.toString(fs[i].getModifiers()) + " ");

// 得到属性类型

System.out.print(fs[i].getType().getSimpleName() + " ");

// 得到属性名

System.out.println(fs[i].getName() + ";");

}

}

public static void printMethods(Class c) {

// 得到方法数组

Method[] md = c.getMethods();

for (int i = 0; i < md.length; i++) {

System.out.println();

System.out.print("t");

// 得到整数形式方法修饰符,使用Modifier进行解码

System.out.print(Modifier.toString(md[i].getModifiers()) + " ");

// 得到方法返回类型

System.out.print(md[i].getGenericReturnType() + " ");

// 得到方法名

System.out.print(md[i].getName() + "(");

// 得到方法参数数组

Class[] paras = md[i].getParameterTypes();

for (int j = 0; j < paras.length; j++) {

System.out.print(paras[j].getSimpleName() + " arg" + j);

if (j < paras.length - 1) {

System.out.print(", ");

}

}

System.out.print(")");

// 得到抛出的异常类数组

Class[] exceps = md[i].getExceptionTypes();

if (exceps.length > 0) {

System.out.print(" throws ");

for (int k = 0; k < exceps.length; k++) {

System.out.print(exceps[k].getSimpleName());

if (k < exceps.length - 1) {

System.out.print(", ");

}

}

}

System.out.println(" {");

System.out.println("tt\\方法体");

System.out.println("t}");

}

}

}

文章来源:guntong

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。