#¤j¼Ð=Java¤Ï®g¾÷¨î #°Æ¼Ð= Java Reflection #§@ªÌ=¤å¡þ«J±¶ # ============= µ{¦¡1 Class class¤ù¬q¡Cª`·N¥¦ªºprivate empty ctor¡A·N«ü¤£¤¹³\¥ô¦ó¤H¸g¥Ñ½sµ{¤è¦¡²£¥ÍClass object¡C¬Oªº¡A¨äobject¥u¯à¥ÑJVM²£¥Í¡C #001 public final #002 class Class implements java.io.Serializable, #003 java.lang.reflect.GenericDeclaration, #004 java.lang.reflect.Type, #005 java.lang.reflect.AnnotatedElement { #006 private Class() {} #007 public String toString() { #008 return ( isInterface() ? "interface " : #009 (isPrimitive() ? "" : "class ")) #010 + getName(); #011 } ... ================ #¤¤¼Ð="Class" objectªº¨ú±o³~®| Java¤¹³\§Ú­Ì±q¦hºØºÞ¹D¬°¤@­Óclass¥Í¦¨¹ïÀ³ªºClass object¡Cªí1¬O¤@¥÷¾ã²z¡C ================= ªí1 Java¤¹³\¦hºØºÞ¹D¥Í¦¨Class object¡C Class object½Ï¥ÍºÞ¹D ¥Ü¨Ò ¹B¥ÎgetClass() µù¡G¨C­Óclass³£¦³¦¹¨ç¦¡ String str = "abc"; Class c1 = str.getClass(); ¹B¥Î Class.getSuperclass()¡]µù2¡^ Button b = new Button(); Class c1 = b.getClass(); Class c2 = c1.getSuperclass(); ¹B¥Îstatic method Class.forName() ¡]³Ì±`³Q¨Ï¥Î¡^ Class c1 = Class.forName ("java.lang.String"); Class c2 = Class.forName ("java.awt.Button"); Class c3 = Class.forName ("java.util.LinkedList$Entry"); Class c4 = Class.forName ("I"); Class c5 = Class.forName ("[I"); ¹B¥Î .class»yªk Class c1 = String.class; Class c2 = java.awt.Button.class; Class c3 = Main.InnerClass.class; Class c4 = int.class; Class c5 = int[].class; ¹B¥Î primitive wrapper classes ªºTYPE»yªk Class c1 = Boolean.TYPE; Class c2 = Byte.TYPE; Class c3 = Character.TYPE; Class c4 = Short.TYPE; Class c5 = Integer.TYPE; Class c6 = Long.TYPE; Class c7 = Float.TYPE; Class c8 = Double.TYPE; Class c9 = Void.TYPE; ================ #¤¤¼Ð=Java classes²Õ¦¨¤ÀªR ­º¥ý®e§Ú¥Hµ{¦¡2ªºjava.util.LinkedList¬°¨Ò¡A±NJava classªº©w¸q¤j¨ø¤K¶ô¡A¨C¤@¶ô¤À§O¹ïÀ³ªí2©Ò¥ÜªºReflection API¡Cµ{¦¡3«h¬O¡uÀò±oclass¦U°Ï¶ô¸ê°T¡vªºµ{¦¡¥Ü¨Ò¤Î°õ¦æµ²ªG¡A¥¦­Ì³£¨ú¦Û¥»¤å¥Ü¨Òµ{¦¡ªº¹ïÀ³¤ù¬q¡C ============= µ{¦¡2 ±N¤@­ÓJava class¤j¨ø¤K¶ô¡A¨C¶ô¬ÛÀ³©ó¤@­Ó©Î¤@²ÕReflection APIs¡]ªí2¡^¡C package java.util; //(1) import java.lang.*; //(2) public class LinkedList //(3)(4)(5) extends AbstractSequentialList //(6) implements List, Queue, Cloneable, java.io.Serializable //(7) { private static class Entry { ¡K } //(8) public LinkedList() { ¡K } //(9) public LinkedList(Collection c) { ¡K } public E getFirst() { ¡K } //(10) public E getLast() { ¡K } private transient Entry header = ¡K; //(11) private transient int size = 0; } ================ #¤¤¼Ð=Java classes¦U¦¨¥÷©Ò¹ïÀ³ªºReflection APIs µ{¦¡2ªº¦U­ÓJava class¦¨¥÷¡A¤À§O¹ïÀ³©óªí2ªºReflection API¡A¨ä¤¤¥X²{ªºPackage, Method, Constructor, Fieldµ¥µ¥classes¡A³£©w¸q©ójava.lang.reflect¡C ================= ªí2 Java class¤j¨ø¤K¶ô«á¡]¦pµ{¦¡2¡^¡A¨C¤@¶ô©Ò¹ïÀ³ªºReflection API¡C¥»ªí¨Ã«DReflection APIsªº¥þ³¡¡C Java class¤º³¡¼Ò¶ô¡]°Ñ¨£µ{¦¡2¡^ Java class¤º³¡¼Ò¶ô»¡©ú ¬ÛÀ³¤§Reflection API. ¦h¥b¬°Class methods. ¶Ç¦^­È«¬§O (return type) (1) package classÁõÄÝ­þ­Ópackage getPackage() Package (2) import class¶×¤J­þ¨Çclasses µLª½±µ¹ïÀ³¤§API¡C ¸Ñ¨M¿ìªk¨£µ{¦¡3-2¡C (3) modifier class¡]©Îmethods, fields¡^ªºÄÝ©Ê int getModifiers() Modifier.toString(int) Modifier.isInterface(int) int String bool (4) class name or interface name class/interface¦WºÙ getName() String (5) type parameters °Ñ¼Æ¤Æ«¬§Oªº¦WºÙ getTypeParameters() TypeVariable [] (6) base class base class¡]¥u¥i¯à¤@­Ó¡^ getSuperClass() Class (7) implemented interfaces ¹ê§@¦³­þ¨Çinterfaces getInterfaces() Class[] (8) inner classes ¤ºÁô¦¡classes getDeclaredClasses() Class[] (8') outer class ¦pªG§Ú­ÌÆ[¹îªºclass¥»¨­¬Oinner classes¡A¨º»ò¬Û¹ï¥¦´N·|¦³­Óouter class¡C getDeclaringClass() Class (9) constructors «Øºc¦¡ getDeclaredConstructors() ¤£½×?public©Îprivate©Î¨ä¥Laccess level¡A¬Ò¥iÀò±o¡C ¥t¦³¥\¯àªñ¦ü¤§¨ú±o¨ç¦¡¡C Constructor[] (10) methods ¾Þ§@¨ç¦¡ getDeclaredMethods() ¤£½×?public©Îprivate©Î¨ä¥Laccess level¡A¬Ò¥iÀò±o¡C ¥t¦³¥\¯àªñ¦ü¤§¨ú±o¨ç¦¡¡C Method[] (11) fields Äæ¦ì¡]¦¨­ûÅܼơ^ getDeclaredFields() ¤£½×?public©Îprivate©Î¨ä¥Laccess level¡A¬Ò¥iÀò±o¡C ¥t¦³¥\¯àªñ¦ü¤§¨ú±o¨ç¦¡¡C Field[] ================ #¤¤¼Ð=Java Reflection API¹B¥Î¥Ü¨Ò µ{¦¡3¥Ü½dªí2´£¹Lªº¨C¤@­ÓReflection API¡A¤Î¨ä°õ¦æµ²ªG¡Cµ{¦¡¤¤¥X²{ªºtName()¬O­Ó»²§U¨ç¦¡¡A¥i±N¨ä²Ä¤@¤Þ¼Æ©Ò¥Nªíªº¡uJava class§¹¾ã¸ô®|¦r¦ê¡v­é°£¸ô®|³¡¤À¡A¯d¤Uclass¦WºÙ¡AÀx¦s¨ì²Ä¤G¤Þ¼Æ©Ò¥Nªíªº¤@­Óhashtable¥h¨Ã¶Ç¦^¡]¦pªG²Ä¤G¤Þ¼Æ¬°null¡A´N¤£Àx¦s¦Ó¥u¬O¶Ç¦^¡^¡C ============= µ{¦¡3-1 §ä¥XclassÁõÄݪºpackage¡C¨ä¤¤ªºc±NÄ~Äòªu¥Î©ó¥H¤U¦Uµ{¦¡¤ù¬q¡C #001 Class c = null; #002 c = Class.forName(args[0]); #003 #004 Package p; #005 p = c.getPackage(); #006 #007 if (p != null) #008 System.out.println("package "+p.getName()+";"); °õ¦æµ²ªG¡]¨Ò¡^¡G package java.util; ================ ============= µ{¦¡3-2 §ä¥X¶×¤Jªºclasses¡A°Ê§@²Ó¸`¸Ô¨£¤º¤å»¡©ú¡C #001 ff = c.getDeclaredFields(); #002 for (int i = 0; i < ff.length; i++) #003 x = tName(ff[i].getType().getName(), classRef); #004 #005 cn = c.getDeclaredConstructors(); #006 for (int i = 0; i < cn.length; i++) { #007 Class cx[] = cn[i].getParameterTypes(); #008 for (int j = 0; j < cx.length; j++) #009 x = tName(cx[j].getName(), classRef); #010 } #011 #012 mm = c.getDeclaredMethods(); #013 for (int i = 0; i < mm.length; i++) { #014 x = tName(mm[i].getReturnType().getName(), classRef); #015 Class cx[] = mm[i].getParameterTypes(); #016 for (int j = 0; j < cx.length; j++) #017 x = tName(cx[j].getName(), classRef); #018 } #019 classRef.remove(c.getName()); //¤£¥²°O¿ý¦Û¤v¡]¤£»Ýimport¦Û¤v¡^ °õ¦æµ²ªG¡]¨Ò¡^¡G import java.util.ListIterator; import java.lang.Object; import java.util.LinkedList$Entry; import java.util.Collection; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; ================ ============= µ{¦¡3-3 §ä¥Xclass©Îinterfaceªº¦WºÙ¡A¤Î¨äÄÝ©Ê¡]modifiers¡^¡C #001 int mod = c.getModifiers(); #002 System.out.print(Modifier.toString(mod)); //¾ã­Ómodifier #003 #004 if (Modifier.isInterface(mod)) #005 System.out.print(" "); //ÃöÁä¦r "interface" ¤w§t©ómodifier #006 else #007 System.out.print(" class "); //ÃöÁä¦r "class" #008 System.out.print(tName(c.getName(), null)); //class¦WºÙ °õ¦æµ²ªG¡]¨Ò¡^¡G public class LinkedList ================ ============= µ{¦¡3-4 §ä¥Xparameterized typesªº¦WºÙ¡C #001 TypeVariable[] tv; #002 tv = c.getTypeParameters(); //warning: unchecked conversion #003 for (int i = 0; i < tv.length; i++) { #004 x = tName(tv[i].getName(), null); //¨Ò¦p E,K,V... #005 if (i == 0) //²Ä¤@­Ó #006 System.out.print("<" + x); #007 else //«D²Ä¤@­Ó #008 System.out.print("," + x); #009 if (i == tv.length-1) //³Ì«á¤@­Ó #010 System.out.println(">"); #011 } °õ¦æµ²ªG¡]¨Ò¡^¡G public abstract interface Map ©Î public class LinkedList ================ ================ µ{¦¡3-5 §ä¥Xbase class¡C°õ¦æµ²ªG¦h¥X¤@­Ó¤£¸Ó¦³ªº³r¸¹©ó§ÀºÝ¡C¦¹«D¥»³B­«ÂI¡A¬°Â²¤Æ­p¡A¤£¦h°µ³B²z¡C #001 Class supClass; #002 supClass = c.getSuperclass(); #003 if (supClass != null) //¦pªG¦³super class #004 System.out.print(" extends" + #005 tName(supClass.getName(),classRef)); °õ¦æµ²ªG¡]¨Ò¡^¡G public class LinkedList extends AbstractSequentialList, ================ ============= µ{¦¡3-6 §ä¥Ximplemented interfaces¡C°õ¦æµ²ªG¦h¥X¤@­Ó¤£¸Ó¦³ªº³r¸¹©ó§ÀºÝ¡C¦¹«D¥»³B­«ÂI¡A¬°Â²¤Æ­p¡A¤£¦h°µ³B²z¡C #001 Class cc[]; #002 Class ctmp; #003 //§ä¥X©Ò¦³³Q¹ê§@ªºinterfaces #004 cc = c.getInterfaces(); #005 if (cc.length != 0) #006 System.out.print(", \r\n" + " implements "); //ÃöÁä¦r #007 for (Class cite : cc) //JDK1.5·s¦¡°j°é¼gªk #008 System.out.print(tName(cite.getName(), null)+", "); °õ¦æµ²ªG¡]¨Ò¡^¡G public class LinkedList extends AbstractSequentialList, implements List, Queue, Cloneable, Serializable, ================ ============= µ{¦¡3-7 / §ä¥Xinner classes©Mouter class¡C #001 cc = c.getDeclaredClasses(); //§ä¥Xinner classes #002 for (Class cite : cc) #003 System.out.println(tName(cite.getName(), null)); #004 #005 ctmp = c.getDeclaringClass(); //§ä¥Xouter classes #006 if (ctmp != null) #007 System.out.println(ctmp.getName()); °õ¦æµ²ªG¡]¨Ò¡^¡G LinkedList$Entry LinkedList$ListItr ================ ============= µ{¦¡3-8a §ä¥X©Ò¦³constructors¡C #001 Constructor cn[]; #002 cn = c.getDeclaredConstructors(); #003 for (int i = 0; i < cn.length; i++) { #004 int md = cn[i].getModifiers(); #005 System.out.print(" " + Modifier.toString(md) + " " + #006 cn[i].getName()); #007 Class cx[] = cn[i].getParameterTypes(); #008 System.out.print("("); #009 for (int j = 0; j < cx.length; j++) { #010 System.out.print(tName(cx[j].getName(), null)); #011 if (j < (cx.length - 1)) System.out.print(", "); #012 } #013 System.out.print(")"); #014 } °õ¦æµ²ªG¡]¨Ò¡^¡G public java.util.LinkedList(Collection) public java.util.LinkedList() ================ ============= µ{¦¡3-8b §ä¥X©Ò¦³constructors¡C¥»¨Ò¦bfor°j°é¤º¨Ï¥ÎtoGenericString()¡A¬Ù¨Æ¡C #004 System.out.println(cn[i].toGenericString()); °õ¦æµ²ªG¡]¨Ò¡^¡G public java.util.LinkedList(java.util.Collection) public java.util.LinkedList() ================ ============= µ{¦¡3-9a §ä¥X©Ò¦³methods¡C #001 Method mm[]; #002 mm = c.getDeclaredMethods(); #003 for (int i = 0; i < mm.length; i++) { #004 int md = mm[i].getModifiers(); #005 System.out.print(" "+Modifier.toString(md)+" "+ #006 tName(mm[i].getReturnType().getName(), null)+" "+ #007 mm[i].getName()); #008 Class cx[] = mm[i].getParameterTypes(); #009 System.out.print("("); #010 for (int j = 0; j < cx.length; j++) { #011 System.out.print(tName(cx[j].getName(), null)); #012 if (j < (cx.length - 1)) System.out.print(", "); #013 } #014 System.out.print(")"); #015 } °õ¦æµ²ªG¡]¨Ò¡^¡G public Object get(int) public int size() ================ ================ µ{¦¡3-9b §ä¥X©Ò¦³methods¡C¥»¨Ò¦bfor°j°é¤º¨Ï¥ÎtoGenericString()¡A¬Ù¨Æ¡C #004 System.out.println(mm[i].toGenericString()); public E java.util.LinkedList.get(int) public int java.util.LinkedList.size() ================ ============= µ{¦¡3-10a §ä¥X©Ò¦³fields¡C #001 Field ff[]; #002 ff = c.getDeclaredFields(); #003 for (int i = 0; i < ff.length; i++) { #004 int md = ff[i].getModifiers(); #005 System.out.println(" "+Modifier.toString(md)+" "+ #006 tName(ff[i].getType().getName(), null) +" "+ #007 ff[i].getName()+";"); #008 } °õ¦æµ²ªG¡]¨Ò¡^¡G private transient LinkedList$Entry header; private transient int size; ================ ============= µ{¦¡3-10b / §ä¥X©Ò¦³fields¡C¥»¨Ò¦bfor°j°é¤º¨Ï¥ÎtoGenericString()¡A¬Ù¨Æ¡C #004 System.out.println("G: " + ff[i].toGenericString()); private transient java.util.LinkedList.java.util.LinkedList$Entry „t java.util.LinkedList.header private transient int java.util.LinkedList.size ================ ============= µ{¦¡4 °ÊºA¥Í¦¨¡uClass object©Ò¹ïÀ³¤§class¡vªºª«¥ó¹êÅé¡FµL¤Þ¼Æ¡C #001 Class c = Class.forName("DynTest"); #002 Object obj = null; #003 obj = c.newInstance(); //¤£±a¤Þ¼Æ #004 System.out.println(obj); ================ ============= µ{¦¡5 °ÊºA¥Í¦¨¡uClass object¹ïÀ³¤§class¡vªºª«¥ó¹êÅé¡F¤Þ¼Æ¥HObject[]ªí¥Ü¡C #001 Class c = Class.forName("DynTest"); #002 Class[] pTypes = new Class[] { double.class, int.class }; #003 Constructor ctor = c.getConstructor(pTypes); #004 //«ü©wparameter list¡A«K¥iÀò±o¯S©w¤§ctor #005 #006 Object obj = null; #007 Object[] arg = new Object[] {3.14159, 125}; //¤Þ¼Æ #008 obj = ctor.newInstance(arg); #009 System.out.println(obj); ================ ============= µ{¦¡6 °ÊºA³ê°_method¡C #001 public String func(String s, Hashtable ht) #002 { #003 ¡KSystem.out.println("func invoked"); return s; #004 } #005 public static void main(String args[]) #006 { #007 Class c = Class.forName("Test"); #008 Class ptypes[] = new Class[2]; #009 ptypes[0] = Class.forName("java.lang.String"); #010 ptypes[1] = Class.forName("java.util.Hashtable"); #011 Method m = c.getMethod("func",ptypes); #012 Test obj = new Test(); #013 Object args[] = new Object[2]; #014 arg[0] = new String("Hello,world"); #015 arg[1] = null; #016 Object r = m.invoke(obj, arg); #017 Integer rval = (String)r; #018 System.out.println(rval); #019 } ================ ============= µ{¦¡7 °ÊºAÅܧófield¤º®e¡C #001 public class Test { #002 public double d; #003 #004 public static void main(String args[]) #005 { #006 Class c = Class.forName("Test"); #007 Field f = c.getField("d"); //«ü©wfield¦WºÙ #008 Test obj = new Test(); #009 System.out.println("d= " + (Double)f.get(obj)); #010 f.set(obj, 12.34); #011 System.out.println("d= " + obj.d); #012 } #013 } ================ ============= µ{¦¡8 ¤@­Ó¥i¦bDOS Box¤¤¨Ï¥Îªº§å¦¸ÀÉ¡]batch file¡^¡A¥Î¥H¦Û°Ê¤Æjava.lang.Classªº­×§ï°Ê§@¡CPkzipc(.exe)¬O­Ó©R¥O¦CÀ£ÁY¤u¨ã¡Aadd©Mpath³£¬O¨ä©R¥O¡C del e:\java\lang\*.class //²M²z°®²b del c:\jdk150\jre\lib\endorsed\foo.jar //²M²z°®²b c: cd c:\jdk150\src\java\lang javac -Xlint:unchecked Class.java //½sĶ·½½X javac -Xlint:unchecked ClassLoader.java //½sĶ¥t¤@­Ó·½½X¡]¦p¦³¥²­n¡^ move *.class e:\java\lang //·h²¾¦Ü¨è·N»s³yªº¥Ø¿ý¤¤ e: cd e:\java\lang //¥H¤UÀ£ÁY¦Ü¾A·í¥Ø¿ý pkzipc -add -path=root c:\jdk150\jre\lib\endorsed\foo.jar *.class cd e:\test //¶i¤J´ú¸Õ¥Ø¿ý javac -Xlint:unchecked Test.java //½sĶ´ú¸Õµ{¦¡ java Test //°õ¦æ´ú¸Õµ{¦¡ ================ ============= ¬ÛÃö¸ê·½ ¥H¤U¬Oµø³¥©Ò¤Î»P¥»¤å¥DÃD¬ÛÃöªº§ó¦h°Q½×¡C³o¨Ç¸ê°T¥i¥HÀ±¸É¦]¤å³¹½g´T­­¨î¦Ó±a¨Óªº¤£¨¬¡A©Î±aµ¹§A§ó¦hµø³¥¡C * "Take an in-depth look at the Java Reflection API -- Learn about the new Java 1.1 tools for finding out information about classes", by Chuck McManis¡C¦¹½g¤å³¹©Òªþµ{¦¡½X¬O¥»¤å¥Ü¨Òµ{¦¡ªº¥D­n¨Ì¾Ú¡]¥»¤å¥Ü¨Òµ{¦¡¥Ü½d¤F§ó¦hReflection APIs¡A¨Ã±Ä¥ÎJDK1.5·s¦¡ªºfor-loop¼gªk¡^¡C * "Take a look inside Java classes -- Learn to deduce properties of a Java class from inside a Java program", by Chuck McManis¡C * "The basics of Java class loaders -- The fundamentals of this key component of the Java architecture", by Chuck McManis¡C * ¡mThe Java Tutorial Continued¡n, Sun microsystems. Lesson58-61, "Reflection". ================