JAVA反射应用.docx
- 文档编号:9869262
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:27
- 大小:23.95KB
JAVA反射应用.docx
《JAVA反射应用.docx》由会员分享,可在线阅读,更多相关《JAVA反射应用.docx(27页珍藏版)》请在冰豆网上搜索。
JAVA反射应用
Java反射应用
JAVA 反射机制的简单应用
开发的时候有时候会碰到这样的情况,我们在写程序的时候并不知道需要调用某个对象的哪个方法,只有程序运行后,我们才能够知道。
或许我们需要根据客户端传过来的某个String 参数的值来判断我们应该执行哪个方法。
在这种情况下JAVA 的反射执行就可以帮上忙了。
下面是我做的一个简单的测试代码,提供给大家做个参考。
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author Dong
* 测试 JAVA reflect 机制
*/
public class TestRef {
/**
* @param args
*/
public static void main(String[] args) {
TestBean test = new TestBean();
Method[] methods = test.getClass().getMethods();
test.setAbc("---");
for ( int i=0;i if (methods[i].getName().equalsIgnoreCase("getabc")) { try { System.out.println(methods[i].invoke(test)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } } JAVA 反射机制 JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java 语言的反射机制。 Java 反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。 1. 得到某个对象的属性 1 public Object getProperty(Object owner, String fieldName) throws Exception { 2 Class ownerClass = owner.getClass(); 3 4 Field field = ownerClass.getField(fieldName); 5 6 Object property = field.get(owner); 7 8 return property; 9 } Class ownerClass = owner.getClass() : 得到该对象的Class 。 Field field = ownerClass.getField(fieldName) : 通过Class 得到类声明的属性。 Object property = field.get(owner) : 通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException 。 2. 得到某个类的静态属性 1 public Object getStaticProperty(String className, String fieldName) 2 throws Exception { 3 Class ownerClass = Class.forName(className); 4 5 Field field = ownerClass.getField(fieldName); 6 7 Object property = field.get(ownerClass); 8 9 return property; 10 } Class ownerClass = Class.forName(className) : 首先得到这个类的Class 。 Field field = ownerClass.getField(fieldName) : 和上面一样,通过Class 得到类声明的属性。 Object property = field.get(ownerClass) : 这里和上面有些不同,因为该属性是静态的,所以直接从类的Class 里取。 3. 执行某对象的方法 1 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception { 2 3 Class ownerClass = owner.getClass(); 4 5 Class[] argsClass = new Class[args.length]; 6 7 for (int i = 0, j = args.length; i < j; i++) { 8 argsClass[i] = args[i].getClass(); 9 } 10 11 Method method = ownerClass.getMethod(methodName, argsClass); 12 13 return method.invoke(owner, args); 14 } Class owner_class = owner.getClass() : 首先还是必须得到这个对象的Class 。 5 ~9 行: 配置参数的Class 数组,作为寻找Method 的条件。 Method method = ownerClass.getMethod(methodName, argsClass) : 通过Method 名和参数的Class 数组得到要执行的Method 。 method.invoke(owner, args) : 执行该Method ,invoke 方法的参数是执行这个方法的对象,和参数数组。 返回值是Object ,也既是该方法的返回值。 4. 执行某个类的静态方法 1 public Object invokeStaticMethod(String className, String methodName, 2 Object[] args) throws Exception { 3 Class ownerClass = Class.forName(className); 4 5 Class[] argsClass = new Class[args.length]; 6 7 for (int i = 0, j = args.length; i < j; i++) { 8 argsClass[i] = args[i].getClass(); 9 } 10 11 Method method = ownerClass.getMethod(methodName, argsClass); 12 13 return method.invoke(null, args); 14 } 基本的原理和实例3 相同,不同点是最后一行,invoke 的一个参数是null ,因为这是静态方法,不需要借助实例运行。 5. 新建实例 1 2 public Object newInstance(String className, Object[] args) throws Exception { 3 Class newoneClass = Class.forName(className); 4 5 Class[] argsClass = new Class[args.length]; 6 7 for (int i = 0, j = args.length; i < j; i++) { 8 argsClass[i] = args[i].getClass(); 9 } 10 11 Constructor cons = newoneClass.getConstructor(argsClass); 12 13 return cons.newInstance(args); 14 15 } 这里说的方法是执行带参数的构造函数来新建实例的方法。 如果不需要参数,可以直接使用newoneClass.newInstance() 来实现。 Class newoneClass = Class.forName(className) : 第一步,得到要构造的实例的Class 。 第5 ~第9 行: 得到参数的Class 数组。 Constructor cons = newoneClass.getConstructor(argsClass) : 得到构造子。 cons.newInstance(args) : 新建实例。 6. 判断是否为某个类的实例 1 public boolean isInstance(Object obj, Class cls) { 2 return cls.isInstance(obj); 3 } 7. 得到数组中的某个元素 1 public Object getByArray(Object array, int index) { 2 return Array.get(array,index); 3 } Java 反射机制深入研究 Java 反射是 Java 语言的一个很重要的特征,它使得 Java 具体了 “ 动态性 ” 。 在 Java 运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法? 对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的。 这种动态获取类的信息以及动态调用对象的方法的功能来自于 Java 语言的反射( Reflection )机制。 Java 反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类。 在运行时构造任意一个类的对象。 在运行时判断任意一个类所具有的成员变量和方法。 在运行时调用任意一个对象的方法。 Reflection 是 Java 被视为动态(或准动态)语言的一个关键性质。 这个机制允许程序在运行时透过 ReflectionAPIs 取得任何一个已知名称的 class 的内部信息,包括其 modifiers (诸如 public,static 等等)、 superclass (例如 Object )、实现之interfaces (例如 Serializable ),也包括 fields 和 methods 的所有信息,并可于运行时改变 fields 内容或调用 methods 。 一般而言,开发者社群说到动态语言,大致认同的一个定义是: “ 程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言” 。 从这个观点看, Perl , Python , Ruby 是动态语言, C++ , Java , C# 不是动态语言。 尽管在这样的定义与分类下 Java 不是动态语言,它却有着一个非常突出的动态相关机制: Reflection 。 这个字的意思是 “ 反射、映象、倒影 ” ,用在 Java 身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的 classes 。 换句话说, Java 程序可以加载一个运行时才得知名称的 class ,获悉其完整构造(但不包括 methods 定义),并生成其对象实体、或对其 fields 设值、或唤起其 methods 。 这种 “ 看透 class” 的能力( theabilityoftheprogramtoexamineitself )被称为 introspection (内省、内观、反省)。 Reflection 和 introspection 是常被并提的两个术语。 在 JDK 中,主要由以下类来实现 Java 反射机制,这些类都位于 java.lang.reflect 包中: Class 类: 代表一个类。 Field 类: 代表类的成员变量(成员变量也称为类的属性)。 Method 类: 代表类的方法。 Constructor 类: 代表类的构造方法。 Array 类: 提供了动态创建数组,以及访问数组的元素的静态方法。 下面给出几个例子看看 ReflectionAPI 的实际运用: 一、通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等 在 java.lang.Object 类中定义了 getClass() 方法,因此对于任意一个 Java 对象,都可以通过此方法获得对象的类型。 Class 类是ReflectionAPI 中的核心类,它有以下方法 getName() : 获得类的完整名字。 getFields() : 获得类的 public 类型的属性。 getDeclaredFields() : 获得类的所有属性。 getMethods() : 获得类的 public 类型的方法。 getDeclaredMethods() : 获得类的所有方法。 getMethod(Stringname,Class[]parameterTypes) : 获得类的特定方法, name 参数指定方法的名字, parameterTypes 参数指定方法的参数类型。 getConstructors() : 获得类的 public 类型的构造方法。 getConstructor(Class[]parameterTypes) : 获得类的特定构造方法, parameterTypes 参数指定构造方法的参数类型。 newInstance() : 通过类的不带参数的构造方法创建这个类的一个对象。 下面给出一个综合运用的例子: publicclassRefConstructor{ publicstaticvoidmain(Stringargs[])throwsException{ RefConstructorref=newRefConstructor(); ref.getConstructor(); } publicvoidgetConstructor()throwsException{ Classc=null; c=Class.forName("java.lang.Long"); Classcs[]={java.lang.String.class}; System.out.println("/n-------------------------------/n"); Constructorcst1=c.getConstructor(cs); System.out.println("1 、通过参数获取指定 Class 对象的构造方法: "); System.out.println(cst1.toString()); Constructorcst2=c.getDeclaredConstructor(cs); System.out.println("2 、通过参数获取指定 Class 对象所表示的类或接口的构造方法: "); System.out.println(cst2.toString()); Constructorcst3=c.getEnclosingConstructor(); System.out.println("3 、获取本地或匿名类 Constructor 对象,它表示基础类的立即封闭构造方法。 "); if(cst3! =null)System.out.println(cst3.toString()); elseSystem.out.println("-- 没有获取到任何构造方法! "); Constructor[]csts=c.getConstructors(); System.out.println("4 、获取指定 Class 对象的所有构造方法: "); for(inti=0;i System.out.println(csts[i].toString()); } System.out.println("/n-------------------------------/n"); Typetypes1[]=c.getGenericInterfaces(); System.out.println("1 、返回直接实现的接口: "); for(inti=0;i System.out.println(types1[i].toString()); } Typetype1=c.getGenericSuperclass(); System.out.println("2 、返回直接超类: "); System.out.println(type1.toString()); Class[]cis=c.getClasses(); System.out.println("3 、返回超类和所有实现的接口: "); for(inti=0;i System.out.println(cis[i].toString()); } Classcs1[]=c.getInterfaces(); System.out.println("4 、实现的接口 "); for(inti=0;i System.out.println(cs1[i].toString()); } System.out.println("/n-------------------------------/n"); Fieldfs1[]=c.getFields(); System.out.println("1 、类或接口的所有可访问公共字段: "); for(inti=0;i System.out.println(fs1[i].toString()); } Fieldf1=c.getField("MIN_VALUE"); System.out.println("2 、类或接口的指定已声明指定公共成员字段: "); System.out.println(f1.toString()); Fieldfs2[]=c.getDeclaredFields(); System.out.println("3 、类或接口所声明的所有字段: "); for(inti=0;i System.out.println(fs2[i].toString()); } Fieldf2=c.getDeclaredField("serialVersionUID"); System.out.println("4 、类或接口的指定已声明指定字段: "); System.out.println(f2.toString()); System.out.println("/n-------------------------------/n"); Methodm1[]=c.getMethods(); System.out.println("1 、返回类所有的公共成员方法: "); for(inti=0;i System.out.println(m1[i].toString()); } Methodm2=c.getMethod("longValue",newClass[]{}); System.out.println("2 、返回指定公共成员方法: "); System.ou
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JAVA 反射 应用
![提示](https://static.bdocx.com/images/bang_tan.gif)