java的反射技术功能十分强大,整理一些资料!! (如需转载,请注明出处!) Lesson: 检测类examing class 1.Retrieving Class Objects 获取一个Class对象(metadata) a,从对象的实例获取。 Class c = mystery.getClass();//(return Class) b,从子类的实例获取 TextField t = new TextField(); Class c = t.getClass(); Class s = c.getSuperclass(); c,知道类名,则可以把.class加入到名字之后来获取。 Class c = java.awt.Button.class; d,如果类名在编译时是未知的,则可以使用Class.forName()方法来获取. Class c = Class.forName(classString); 2.Getting the Class Name 获取类名称 c.getName(); 例如: import java.lang.reflect.*; import java.awt.*; class SampleName { public static void main(String[] args) { Button b = new Button(); printName(b); } static void printName(Object o) { Class c = o.getClass(); String s = c.getName(); System.out.println(s); } } 3.Discovering Class Modifiers 检索修改符 a.通过getModifiers()方法获取一个整型标识值。 b.通过java.reflect.Modifier对象的isPublic, isAbstract, 和 isFinal方法判断此值. 例如: import java.lang.reflect.*; import java.awt.*; class SampleModifier { public static void main(String[] args) { String s = new String(); printModifiers(s); } public static void printModifiers(Object o) { Class c = o.getClass(); int m = c.getModifiers(); if (Modifier.isPublic(m)) System.out.println("public"); if (Modifier.isAbstract(m)) System.out.println("abstract"); if (Modifier.isFinal(m)) System.out.println("final"); } } 4.Finding Superclasses 检索父类 例如: import java.lang.reflect.*; import java.awt.*; class SampleSuper { public static void main(String[] args) { Button b = new Button(); printSuperclasses(b); } static void printSuperclasses(Object o) { Class subclass = o.getClass(); Class superclass = subclass.getSuperclass(); while (superclass != null) { String className = superclass.getName(); System.out.println(className); subclass = superclass; superclass = subclass.getSuperclass(); } } } 5.Identifying the Interfaces Implemented by a Class 检索指定类实现的接口 例如: import java.lang.reflect.*; import java.io.*; class SampleInterface { public static void main(String[] args) { try { RandomAccessFile r = new RandomAccessFile("myfile", "r"); printInterfaceNames(r); } catch (IOException e) { System.out.println(e); } } static void printInterfaceNames(Object o) { Class c = o.getClass(); Class[] theInterfaces = c.getInterfaces(); for (int i = 0; i < theInterfaces.length; i++) { String interfaceName = theInterfaces[i].getName(); System.out.println(interfaceName); } } } 6.Examining Interfaces 判定一个类是不是接口 import java.lang.reflect.*; import java.util.*; class SampleCheckInterface { public static void main(String[] args) { Class thread = Thread.class; Class runnable = Runnable.class; verifyInterface(thread); verifyInterface(runnable); } static void verifyInterface(Class c) { String name = c.getName(); if (c.isInterface()) { System.out.println(name + " is an interface."); } else { System.out.println(name + " is a class."); } } } 如:c.isInterface() 7.Identifying Class Fields 找出指定类所有的域成员 每个数据成员可以用java.reflect.Field来封闭其名称,类型,修改符的集合。 也可以通过相应的方法获取或设置到该成员的值。 如: import java.lang.reflect.*; import java.awt.*; class SampleField { public static void main(String[] args) { GridBagConstraints g = new GridBagConstraints(); printFieldNames(g); } static void printFieldNames(Object o) { Class c = o.getClass(); Field[] publicFields = c.getFields(); for (int i = 0; i < publicFields.length; i++) { String fieldName = publicFields[i].getName(); Class typeClass = publicFields[i].getType(); String fieldType = typeClass.getName(); System.out.println("Name: " + fieldName + ", Type: " + fieldType); } } } 8.Discovering Class Constructors 检索指定类的构造函数 当创建一个类的实例时,是通过检造方法来作的,这种方法可以被重载。 每一个构造方法可以用类Constructor来描述,,包括名称,修饰符,参数类型(Class[]),和异常列表。 可以通过一个Class的getConstructors方法获取到该类的Constructor数组。 例程: import java.lang.reflect.*; import java.awt.*; class SampleConstructor { public static void main(String[] args) { Rectangle r = new Rectangle(); showConstructors(r); } static void showConstructors(Object o) { Class c = o.getClass(); Constructor[] theConstructors = c.getConstructors(); for (int i = 0; i < theConstructors.length; i++) { System.out.print("( "); Class[] parameterTypes = theConstructors[i].getParameterTypes(); for (int k = 0; k < parameterTypes.length; k ++) { String parameterString = parameterTypes[k].getName(); System.out.print(parameterString + " "); } System.out.println(")"); } } } 9.Obtaining Method Information 检索方法 可以找到隶属于一个类的所有方法,通过getMethods包含Method数组,进而得到该方法的返回类型,修饰符,方法名称,参数列表 步骤: a.指定类的Class Object b.getMethods()获取Method[]对象 c,遍历该数组对象 例程: import java.lang.reflect.*; import java.awt.*; class SampleMethod { public static void main(String[] args) { Polygon p = new Polygon(); showMethods(p); } static void showMethods(Object o) { Class c = o.getClass(); Method[] theMethods = c.getMethods(); for (int i = 0; i < theMethods.length; i++) { String methodString = theMethods[i].getName(); System.out.println("Name: " + methodString); String returnString = theMethods[i].getReturnType().getName(); System.out.println(" Return Type: " + returnString); Class[] parameterTypes = theMethods[i].getParameterTypes(); System.out.print(" Parameter Types:"); for (int k = 0; k < parameterTypes.length; k ++) { String parameterString = parameterTypes[k].getName(); System.out.print(" " + parameterString); } System.out.println(); } } } Lesson:2 处理对象 1.Creating Objects 一般情况下,创建一个对象用以下方法 Rectangle r = new Rectangle(); 但如果你正在开发一个development tools,在运行之前或许不知道要生成对象的类。 所以要像下面这样来创建对象: String className; // . . . load className from the user interface Object o = new (className); // WRONG! 但以上是错误的。 正确的方法是使用类的反射特性: 1)Using No-Argument Constructors 例如: Class classDefinition = Class.forName(className);//指定类的运行期实例 object = classDefinition.newInstance();//调用无参构造函数来生成指定类的实例。 2)Using Constructors that Have Arguments 这个技术要用到如下步骤: a,创建一个Class对象 b,创建一个Constructor对象,getConstructor(Class[] params)方法,参数是一个与构造方法相适合的Class 数组. c,在Constructor对象上调用newInstance方法来生成一个对象,参数 是一个object数组与这个构造方法相配备。 例如: import java.lang.reflect.*; import java.awt.*; class SampleInstance { public static void main(String[] args) { Rectangle rectangle; Class rectangleDefinition; Class[] intArgsClass = new Class[] {int.class, int.class}; Integer height = new Integer(12); Integer width = new Integer(34); Object[] intArgs = new Object[] {height, width}; Constructor intArgsConstructor; try { //1. rectangleDefinition = Class.forName("java.awt.Rectangle"); //2. intArgsConstructor = rectangleDefinition.getConstructor(intArgsClass);//找到指定的构造方法 //3. rectangle = (Rectangle) createObject(intArgsConstructor, intArgs);//构造方法描述对象,object[] } catch (ClassNotFoundException e) { System.out.println(e); } catch (NoSuchMethodException e) { System.out.println(e); } } public static Object createObject(Constructor constructor, Object[] arguments) { System.out.println ("Constructor: " + constructor.toString()); Object object = null; try { object = constructor.newInstance(arguments); System.out.println ("Object: " + object.toString()); return object; } catch (InstantiationException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } catch (IllegalArgumentException e) { System.out.println(e); } catch (InvocationTargetException e) { System.out.println(e); } return object; } } 2。Getting Field Values If you are writing a development tool such as a debugger, you must be able to obtain field values. This is a three-step process: 如果要作一个开发工具像debugger之类的,你必须能发现filed values,以下是三个步骤: a.创建一个Class对象 b.通过getField 创建一个Field对象 c.调用Field.getXXX(Object)方法(XXX是Int,Float等,如果是对象就省略;Object是指实 例). 例如: import java.lang.reflect.*; import java.awt.*; class SampleGet { public static void main(String[] args) { Rectangle r = new Rectangle(100, 325); printHeight(r); } static void printHeight(Rectangle r) { Field heightField; Integer heightValue; Class c = r.getClass(); try { heightField = c.getField("height"); heightValue = (Integer) heightField.get(r); System.out.println("Height: " + heightValue.toString()); } catch (NoSuchFieldException e) { System.out.println(e); } catch (SecurityException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } } } 3。Setting Field Values a.创建一个Class对象 b.通过getField 创建一个Field对象 c.调用Field.set(Object,withparam)方法(XXX是Int,Float等,如果是对象就省略;Object是指实例,withparam指和这个字段相区配的字段。 import java.lang.reflect.*; import java.awt.*; class SampleSet { public static void main(String[] args) { Rectangle r = new Rectangle(100, 20); System.out.println("original: " + r.toString()); modifyWidth(r, new Integer(300)); System.out.println("modified: " + r.toString()); } static void modifyWidth(Rectangle r, Integer widthParam ) { Field widthField; Integer widthValue; Class c = r.getClass(); try { widthField = c.getField("width"); widthField.set(r, widthParam); } catch (NoSuchFieldException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } } } 4。调用指定的方法 a.创建一个Class对象 b.创建一个方法对象method,getMethod(String methodName,Class[])方法 c.调方法对象,method.invoke(object,Object[]),两个参数,第一个是指调用方法所属于的对象,第二个是传递的值对象列表。 The sample program that follows shows you how to invoke a method dynamically. The program retrieves the Method object for the String.concat method and then uses invoke to concatenate two String objects. // import java.lang.reflect.*; class SampleInvoke { public static void main(String[] args) { String firstWord = "Hello "; //指定类的实例 String secondWord = "everybody.";//变元 String bothWords = append(firstWord, secondWord); System.out.println(bothWords); } public static String append(String firstWord, String secondWord) { String result = null; Class c = String.class; Class[] parameterTypes = new Class[] {String.class}; Method concatMethod; Object[] arguments = new Object[] {secondWord}; try { concatMethod = c.getMethod("concat", parameterTypes);//获取到方法对象 result = (String) concatMethod.invoke(firstWord, arguments);//调用 } catch (NoSuchMethodException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } catch (InvocationTargetException e) { System.out.println(e); } return result; } } |