1、按如下语句执行:java DumpMethods java.util.Stack它的结果输出为:public java.lang.Object java.util.Stack.push(java.lang.Object)public synchronized java.lang.Object java.util.Stack.pop()public synchronized java.lang.Object java.util.Stack.peek()public boolean java.util.Stack.empty()public synchronized int java.util.S
2、tack.search(java.lang.Object)这样就列出了java.util.Stack 类的各方法名以及它们的限制符和返回类型。这个程序使用 Class.forName 载入指定的类,然后调用 getDeclaredMethods 来获取这个类中定义了的方法列表。java.lang.reflect.Methods 是用来描述某个类中单个方法的一个类。1.2 Java类反射中的主要方法对于以下三类组件中的任何一类来说 - 构造函数、字段和方法 - java.lang.Class 提供四种独立的反射调用,以不同的方式来获得信息。调用都遵循一种标准格式。以下是用于查找构造函数的一组反射
3、调用l Constructor getConstructor(Class params) - 获得使用特殊的参数类型的公共构造函数,l Constructor getConstructors() - 获得类的所有公共构造函数l Constructor getDeclaredConstructor(Class params) - 获得使用特定参数类型的构造函数(与接入级别无关)l Constructor getDeclaredConstructors() - 获得类的所有构造函数(与接入级别无关) 获得字段信息的Class 反射调用不同于那些用于接入构造函数的调用,在参数类型数组中使用了字段名:
4、l Field getField(String name) - 获得命名的公共字段l Field getFields() - 获得类的所有公共字段l Field getDeclaredField(String name) - 获得类声明的命名的字段l Field getDeclaredFields() - 获得类声明的所有字段 用于获得方法信息函数:l Method getMethod(String name, Class params) - 使用特定的参数类型,获得命名的公共方法l Method getMethods() - 获得类的所有公共方法l Method getDeclaredMet
5、hod(String name, Class params) - 使用特写的参数类型,获得类声明的命名的方法l Method getDeclaredMethods() - 获得类声明的所有方法1.3开始使用 Reflection:用于 reflection 的类,如 Method,可以在 java.lang.relfect 包中找到。使用这些类的时候必须要遵循三个步骤:第一步是获得你想操作的类的 java.lang.Class 对象。在运行中的 Java 程序中,用 java.lang.Class 类来描述类和接口等。下面就是获得一个 Class 对象的方法之一:Class c = Class
6、.forName(java.lang.String);这条语句得到一个 String 类的类对象。还有另一种方法,如下面的语句:Class c = int.class;或者Class c = Integer.TYPE;它们可获得基本类型的类信息。其中后一种方法中访问的是基本类型的封装类 (如 Integer) 中预先定义好的 TYPE 字段。第二步是调用诸如 getDeclaredMethods 的方法,以取得该类中定义的所有方法的列表。一旦取得这个信息,就可以进行第三步了使用 reflection API 来操作这些信息,如下面这段代码:Method m = c.getDeclaredMet
7、hods();System.out.println(m0.toString();它将以文本方式打印出 String 中定义的第一个方法的原型。2处理对象:如果要作一个开发工具像debugger之类的,你必须能发现filed values,以下是三个步骤:a.创建一个Class对象b.通过getField 创建一个Field对象c.调用Field.getXXX(Object)方法(XXX是Int,Float等,如果是对象就省略;Object是指实例).例如:import java.awt.*;class SampleGet public static void main(String args)
8、 Rectangle r = new Rectangle(100, 325); printHeight(r); static void printHeight(Rectangle r) Field heightField; Integer heightValue; Class c = r.getClass(); heightField = c.getField(height heightValue = (Integer) heightField.get(r); System.out.println(Height: + heightValue.toString(); catch (NoSuchF
9、ieldException e) System.out.println(e); catch (SecurityException e) catch (IllegalAccessException e) 三、安全性和反射:在处理反射时安全性是一个较复杂的问题。反射经常由框架型代码使用,由于这一点,我们可能希望框架能够全面接入代码,无需考虑常规的接入限制。但是,在其它情况下,不受控制的接入会带来严重的安全性风险,例如当代码在不值得信任的代码共享的环境中运行时。Java编程语言定义一种多级别方法来处理反射的安全性。基本模式是对反射实施与应用于源代码接入相同的限制:n 从任意位置到类公共组件的接入n
10、类自身外部无任何到私有组件的接入n 受保护和打包(缺省接入)组件的有限接入不过至少有些时候,围绕这些限制还有一种简单的方法。我们可以在我们所写的类中,扩展一个普通的基本类java.lang.reflect.AccessibleObject 类。这个类定义了一种setAccessible方法,使我们能够启动或关闭对这些类中其中一个类的实例的接入检测。唯一的问题在于如果使用了安全性管理器,它将检测正在关闭接入检测的代码是否许可了这样做。如果未许可,安全性管理器抛出一个例外。下面是一段程序,在TwoString 类的一个实例上使用反射来显示安全性正在运行:public class ReflectSe
11、curity TwoString ts = new TwoString(a, b Field field = clas.getDeclaredField(m_s1/ field.setAccessible(true);Retrieved value is + field.get(inst); catch (Exception ex) ex.printStackTrace(System.out);如果我们编译这一程序时,不使用任何特定参数直接从命令行运行,它将在field .get(inst)调用中抛出一个IllegalAccessException异常。如果我们不注释field.setAcce
12、ssible(true)代码行,那么重新编译并重新运行该代码,它将编译成功。最后,如果我们在命令行添加了JVM参数-Djava.security.manager以实现安全性管理器,它仍然将不能通过编译,除非我们定义了ReflectSecurity类的许可权限。四、反射性能:下面的程序是字段接入性能测试的一个例子,包括基本的测试方法。每种方法测试字段接入的一种形式 - accessSame 与同一对象的成员字段协作,accessOther 使用可直接接入的另一对象的字段,accessReflection 使用可通过反射接入的另一对象的字段。在每种情况下,方法执行相同的计算 - 循环中简单的加/乘
13、顺序。程序如下:public int accessSame(int loops) m_value = 0; for (int index = 0; index 0) name = args0; else name = JOptionPane.showInputDialog(输入一个类名:按(java.lang.Double)格式 try Class cl = Class.forName(name); Class supercl = cl.getSuperclass(); /获得超类的Class对象class /判断超类是否为空或为Object if (supercl != null & sup
14、ercl != Object.class)extends + supercl.getName(); System.out.print(nn printConstructors(cl); System.out.println(); printMethods(cl); printField(cl); /当使用class对象时注意捕获该异常,异常为类型未创建 catch(ClassNotFoundException e) e.printStackTrace();类型未创建 System.exit(0); /* *该方法打印构造器的详细信息 */ public static void printCon
15、structors(Class cl) /定义构造器数组 Constructor constructors = cl.getDeclaredConstructors(); constructors.length; /将数组元素赋给一个构造器对象 Constructor constr = constructorsi; String name = constr.getName(); /获取构造器名称 /打印访问修饰符 System.out.print(Modifier.toString(constr.getModifiers();+ name + ( *定义一个参数类型数组该数组是Class对象
16、*getParameterTypes()返回该构造器参数类型的数组 *打印参数类型名称 Class paramTypes = constr.getParameterTypes(); for (int j = 0; j 0) System.out.print( System.out.print(paramTypesj.getName(); *该方法打印方法的详细信息 public static void printMethods(Class cl) Method methods = cl.getDeclaredMethods(); methods.length; Method m = methodsi; Class retType = m.getReturnType(); String name = m.getName(); System.out.print(Modifier.toString(m.getModifiers();+ retType.getName() + Class paramTypes = m.getParameterTypes(); *该方法打印字段的详细信息 public static void printField(Class cl) Field fields = cl.getDeclaredFields();
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2