• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2006 The Android Open Source Project
2 
3 import java.lang.reflect.*;
4 import java.io.IOException;
5 import java.util.Collections;
6 import java.util.ArrayList;
7 import java.util.List;
8 import java.util.Map;
9 
10 /**
11  * Reflection test.
12  */
13 public class Main {
14     private static boolean FULL_ACCESS_CHECKS = false;  // b/5861201
Main()15     public Main() {}
Main(ArrayList<Integer> stuff)16     public Main(ArrayList<Integer> stuff) {}
17 
printMethodInfo(Method meth)18     void printMethodInfo(Method meth) {
19         Class[] params, exceptions;
20         int i;
21 
22         System.out.println("Method name is " + meth.getName());
23         System.out.println(" Declaring class is "
24             + meth.getDeclaringClass().getName());
25         params = meth.getParameterTypes();
26         for (i = 0; i < params.length; i++)
27             System.out.println(" Arg " + i + ": " + params[i].getName());
28         exceptions = meth.getExceptionTypes();
29         for (i = 0; i < exceptions.length; i++)
30             System.out.println(" Exc " + i + ": " + exceptions[i].getName());
31         System.out.println(" Return type is " + meth.getReturnType().getName());
32         System.out.println(" Access flags are 0x"
33             + Integer.toHexString(meth.getModifiers()));
34         //System.out.println(" GenericStr is " + meth.toGenericString());
35     }
36 
printFieldInfo(Field field)37     void printFieldInfo(Field field) {
38         System.out.println("Field name is " + field.getName());
39         System.out.println(" Declaring class is "
40             + field.getDeclaringClass().getName());
41         System.out.println(" Field type is " + field.getType().getName());
42         System.out.println(" Access flags are 0x"
43             + Integer.toHexString(field.getModifiers()));
44     }
45 
showStrings(Target instance)46     private void showStrings(Target instance)
47         throws NoSuchFieldException, IllegalAccessException {
48 
49         Class target = Target.class;
50         String one, two, three, four;
51         Field field = null;
52 
53         field = target.getField("string1");
54         one = (String) field.get(instance);
55 
56         field = target.getField("string2");
57         two = (String) field.get(instance);
58 
59         field = target.getField("string3");
60         three = (String) field.get(instance);
61 
62         System.out.println("  ::: " + one + ":" + two + ":" + three);
63     }
64 
checkAccess()65     public static void checkAccess() {
66         try {
67             Class target = otherpackage.Other.class;
68             Object instance = new otherpackage.Other();
69             Method meth;
70 
71             meth = target.getMethod("publicMethod", (Class[]) null);
72             meth.invoke(instance);
73 
74             try {
75                 meth = target.getMethod("packageMethod", (Class[]) null);
76                 System.err.println("succeeded on package-scope method");
77             } catch (NoSuchMethodException nsme) {
78                 // good
79             }
80 
81 
82             instance = otherpackage.Other.getInnerClassInstance();
83             target = instance.getClass();
84             meth = target.getMethod("innerMethod", (Class[]) null);
85             try {
86                 if (!FULL_ACCESS_CHECKS) { throw new IllegalAccessException(); }
87                 meth.invoke(instance);
88                 System.err.println("inner-method invoke unexpectedly worked");
89             } catch (IllegalAccessException iae) {
90                 // good
91             }
92 
93             Field field = target.getField("innerField");
94             try {
95                 int x = field.getInt(instance);
96                 if (!FULL_ACCESS_CHECKS) { throw new IllegalAccessException(); }
97                 System.err.println("field get unexpectedly worked: " + x);
98             } catch (IllegalAccessException iae) {
99                 // good
100             }
101         } catch (Exception ex) {
102             System.out.println("----- unexpected exception -----");
103             ex.printStackTrace();
104         }
105     }
106 
run()107     public void run() {
108         Class target = Target.class;
109         Method meth = null;
110         Field field = null;
111         boolean excep;
112 
113         try {
114             meth = target.getMethod("myMethod", new Class[] { int.class });
115 
116             if (meth.getDeclaringClass() != target)
117                 throw new RuntimeException();
118             printMethodInfo(meth);
119 
120             meth = target.getMethod("myMethod", new Class[] { float.class });
121             printMethodInfo(meth);
122 
123             meth = target.getMethod("myNoargMethod", (Class[]) null);
124             printMethodInfo(meth);
125 
126             meth = target.getMethod("myMethod",
127                 new Class[] { String[].class, float.class, char.class });
128             printMethodInfo(meth);
129 
130             Target instance = new Target();
131             Object[] argList = new Object[] {
132                 new String[] { "hi there" },
133                 new Float(3.1415926f),
134                 new Character('Q')
135             };
136             System.out.println("Before, float is "
137                 + ((Float)argList[1]).floatValue());
138 
139             Integer boxval;
140             boxval = (Integer) meth.invoke(instance, argList);
141             System.out.println("Result of invoke: " + boxval.intValue());
142 
143             System.out.println("Calling no-arg void-return method");
144             meth = target.getMethod("myNoargMethod", (Class[]) null);
145             meth.invoke(instance, (Object[]) null);
146 
147             /* try invoking a method that throws an exception */
148             meth = target.getMethod("throwingMethod", (Class[]) null);
149             try {
150                 meth.invoke(instance, (Object[]) null);
151                 System.out.println("GLITCH: didn't throw");
152             } catch (InvocationTargetException ite) {
153                 System.out.println("Invoke got expected exception:");
154                 System.out.println(ite.getClass().getName());
155                 System.out.println(ite.getCause());
156             }
157             catch (Exception ex) {
158                 System.out.println("GLITCH: invoke got wrong exception:");
159                 ex.printStackTrace();
160             }
161             System.out.println("");
162 
163 
164             field = target.getField("string1");
165             if (field.getDeclaringClass() != target)
166                 throw new RuntimeException();
167             printFieldInfo(field);
168             String strVal = (String) field.get(instance);
169             System.out.println("  string1 value is '" + strVal + "'");
170 
171             showStrings(instance);
172 
173             field.set(instance, new String("a new string"));
174             strVal = (String) field.get(instance);
175             System.out.println("  string1 value is now '" + strVal + "'");
176 
177             showStrings(instance);
178 
179             try {
180                 field.set(instance, new Object());
181                 System.out.println("WARNING: able to store Object into String");
182             }
183             catch (IllegalArgumentException iae) {
184                 System.out.println("  got expected illegal obj store exc");
185             }
186 
187 
188             try {
189                 String four;
190                 field = target.getField("string4");
191                 four = (String) field.get(instance);
192                 System.out.println("WARNING: able to access string4: "
193                     + four);
194             }
195             catch (IllegalAccessException iae) {
196                 System.out.println("  got expected access exc");
197             }
198             catch (NoSuchFieldException nsfe) {
199                 System.out.println("  got the other expected access exc");
200             }
201             try {
202                 String three;
203                 field = target.getField("string3");
204                 three = (String) field.get(this);
205                 System.out.println("WARNING: able to get string3 in wrong obj: "
206                     + three);
207             }
208             catch (IllegalArgumentException iae) {
209                 System.out.println("  got expected arg exc");
210             }
211 
212             /*
213              * Try setting a field to null.
214              */
215             String four;
216             field = target.getDeclaredField("string3");
217             field.set(instance, null);
218 
219             /*
220              * Do some stuff with long.
221              */
222             long longVal;
223             field = target.getField("pubLong");
224             longVal = field.getLong(instance);
225             System.out.println("pubLong initial value is " +
226                 Long.toHexString(longVal));
227             field.setLong(instance, 0x9988776655443322L);
228             longVal = field.getLong(instance);
229             System.out.println("pubLong new value is " +
230                 Long.toHexString(longVal));
231 
232 
233             field = target.getField("superInt");
234             if (field.getDeclaringClass() == target)
235                 throw new RuntimeException();
236             printFieldInfo(field);
237             int intVal = field.getInt(instance);
238             System.out.println("  superInt value is " + intVal);
239             Integer boxedIntVal = (Integer) field.get(instance);
240             System.out.println("  superInt boxed is " + boxedIntVal);
241 
242             field.set(instance, new Integer(20202));
243             intVal = field.getInt(instance);
244             System.out.println("  superInt value is now " + intVal);
245             field.setShort(instance, (short)30303);
246             intVal = field.getInt(instance);
247             System.out.println("  superInt value (from short) is now " +intVal);
248             field.setInt(instance, 40404);
249             intVal = field.getInt(instance);
250             System.out.println("  superInt value is now " + intVal);
251             try {
252                 field.set(instance, new Long(123));
253                 System.out.println("FAIL: expected exception not thrown");
254             }
255             catch (IllegalArgumentException iae) {
256                 System.out.println("  got expected long->int failure");
257             }
258             try {
259                 field.setLong(instance, 123);
260                 System.out.println("FAIL: expected exception not thrown");
261             }
262             catch (IllegalArgumentException iae) {
263                 System.out.println("  got expected long->int failure");
264             }
265             try {
266                 field.set(instance, new String("abc"));
267                 System.out.println("FAIL: expected exception not thrown");
268             }
269             catch (IllegalArgumentException iae) {
270                 System.out.println("  got expected string->int failure");
271             }
272 
273             try {
274                 field.getShort(instance);
275                 System.out.println("FAIL: expected exception not thrown");
276             }
277             catch (IllegalArgumentException iae) {
278                 System.out.println("  got expected int->short failure");
279             }
280 
281             field = target.getField("superClassInt");
282             printFieldInfo(field);
283             int superClassIntVal = field.getInt(instance);
284             System.out.println("  superClassInt value is " + superClassIntVal);
285 
286             field = target.getField("staticDouble");
287             printFieldInfo(field);
288             double staticDoubleVal = field.getDouble(null);
289             System.out.println("  staticDoubleVal value is " + staticDoubleVal);
290 
291             try {
292                 field.getLong(instance);
293                 System.out.println("FAIL: expected exception not thrown");
294             }
295             catch (IllegalArgumentException iae) {
296                 System.out.println("  got expected double->long failure");
297             }
298 
299             excep = false;
300             try {
301                 field = target.getField("aPrivateInt");
302                 printFieldInfo(field);
303             }
304             catch (NoSuchFieldException nsfe) {
305                 System.out.println("as expected: aPrivateInt not found");
306                 excep = true;
307             }
308             if (!excep)
309                 System.out.println("BUG: got aPrivateInt");
310 
311 
312             field = target.getField("constantString");
313             printFieldInfo(field);
314             String val = (String) field.get(instance);
315             System.out.println("  Constant test value is " + val);
316 
317 
318             field = target.getField("cantTouchThis");
319             printFieldInfo(field);
320             intVal = field.getInt(instance);
321             System.out.println("  cantTouchThis is " + intVal);
322             try {
323                 field.setInt(instance, 99);
324                 System.out.println("ERROR: set-final succeeded");
325             } catch (IllegalAccessException iae) {
326                 System.out.println("  got expected set-final failure");
327             }
328             intVal = field.getInt(instance);
329             System.out.println("  cantTouchThis is now " + intVal);
330 
331             field.setAccessible(true);
332             field.setInt(instance, 87);     // exercise int version
333             field.set(instance, 88);        // exercise Object version
334             intVal = field.getInt(instance);
335             System.out.println("  cantTouchThis is now " + intVal);
336 
337             Constructor<Target> cons;
338             Target targ;
339             Object[] args;
340 
341             cons = target.getConstructor(new Class[] { int.class,float.class });
342             args = new Object[] { new Integer(7), new Float(3.3333) };
343             System.out.println("cons modifiers=" + cons.getModifiers());
344             targ = cons.newInstance(args);
345             targ.myMethod(17);
346 
347         } catch (Exception ex) {
348             System.out.println("----- unexpected exception -----");
349             ex.printStackTrace();
350         }
351 
352         System.out.println("ReflectTest done!");
353     }
354 
checkType()355     public static void checkType() {
356         Method m;
357 
358         try {
359             m = Collections.class.getDeclaredMethod("checkType",
360                             Object.class, Class.class);
361         } catch (NoSuchMethodException nsme) {
362             nsme.printStackTrace();
363             return;
364         }
365 
366         m.setAccessible(true);
367         try {
368             m.invoke(null, new Object(), Object.class);
369         } catch (IllegalAccessException iae) {
370             iae.printStackTrace();
371             return;
372         } catch (InvocationTargetException ite) {
373             ite.printStackTrace();
374             return;
375         }
376 
377         try {
378             System.out.println("checkType invoking null");
379             m.invoke(null, new Object(), int.class);
380             System.out.println("ERROR: should throw InvocationTargetException");
381         } catch (InvocationTargetException ite) {
382             System.out.println("checkType got expected exception");
383         } catch (IllegalAccessException iae) {
384             iae.printStackTrace();
385             return;
386         }
387     }
388 
checkInit()389     public static void checkInit() {
390         Class niuClass = NoisyInitUser.class;
391         Method[] methods;
392 
393         methods = niuClass.getDeclaredMethods();
394         System.out.println("got methods");
395         /* neither NoisyInit nor NoisyInitUser should be initialized yet */
396         NoisyInitUser niu = new NoisyInitUser();
397         NoisyInit ni = new NoisyInit();
398 
399         System.out.println("");
400     }
401 
402 
403     /*
404      * Test some generic type stuff.
405      */
406     public List<String> dummy;
fancyMethod(ArrayList<String> blah)407     public Map<Integer,String> fancyMethod(ArrayList<String> blah) { return null; }
checkGeneric()408     public static void checkGeneric() {
409         Field field;
410         try {
411             field = Main.class.getField("dummy");
412         } catch (NoSuchFieldException nsfe) {
413             throw new RuntimeException(nsfe);
414         }
415         Type listType = field.getGenericType();
416         System.out.println("generic field: " + listType);
417 
418         Method method;
419         try {
420             method = Main.class.getMethod("fancyMethod",
421                 new Class[] { ArrayList.class });
422         } catch (NoSuchMethodException nsme) {
423             throw new RuntimeException(nsme);
424         }
425         Type[] parmTypes = method.getGenericParameterTypes();
426         Type ret = method.getGenericReturnType();
427         System.out.println("generic method " + method.getName() + " params='"
428             + stringifyTypeArray(parmTypes) + "' ret='" + ret + "'");
429 
430         Constructor ctor;
431         try {
432             ctor = Main.class.getConstructor(new Class[] { ArrayList.class });
433         } catch (NoSuchMethodException nsme) {
434             throw new RuntimeException(nsme);
435         }
436         parmTypes = ctor.getGenericParameterTypes();
437         System.out.println("generic ctor " + ctor.getName() + " params='"
438             + stringifyTypeArray(parmTypes) + "'");
439     }
440 
441     /*
442      * Convert an array of Type into a string.  Start with an array count.
443      */
stringifyTypeArray(Type[] types)444     private static String stringifyTypeArray(Type[] types) {
445         StringBuilder stb = new StringBuilder();
446         boolean first = true;
447 
448         stb.append("[" + types.length + "]");
449 
450         for (Type t: types) {
451             if (first) {
452                 stb.append(" ");
453                 first = false;
454             } else {
455                 stb.append(", ");
456             }
457             stb.append(t.toString());
458         }
459 
460         return stb.toString();
461     }
462 
463 
main(String[] args)464     public static void main(String[] args) {
465         Main test = new Main();
466         test.run();
467 
468         checkAccess();
469         checkType();
470         checkInit();
471         checkGeneric();
472     }
473 }
474 
475 
476 class SuperTarget {
SuperTarget()477     public SuperTarget() {
478         System.out.println("SuperTarget constructor ()V");
479         superInt = 1010101;
480         superClassInt = 1010102;
481     }
482 
myMethod(float floatArg)483     public int myMethod(float floatArg) {
484         System.out.println("myMethod (F)I " + floatArg);
485         return 6;
486     }
487 
488     public int superInt;
489     public static int superClassInt;
490 }
491 
492 class Target extends SuperTarget {
Target()493     public Target() {
494         System.out.println("Target constructor ()V");
495     }
496 
Target(int ii, float ff)497     public Target(int ii, float ff) {
498         System.out.println("Target constructor (IF)V : ii="
499             + ii + " ff=" + ff);
500         anInt = ii;
501     }
502 
myMethod(int intarg)503     public int myMethod(int intarg) throws NullPointerException, IOException {
504         System.out.println("myMethod (I)I");
505         System.out.println(" arg=" + intarg + " anInt=" + anInt);
506         return 5;
507     }
508 
myMethod(String[] strarg, float f, char c)509     public int myMethod(String[] strarg, float f, char c) {
510         System.out.println("myMethod: " + strarg[0] + " " + f + " " + c + " !");
511         return 7;
512     }
513 
myNoargMethod()514     public static void myNoargMethod() {
515         System.out.println("myNoargMethod ()V");
516     }
517 
throwingMethod()518     public void throwingMethod() {
519         System.out.println("throwingMethod");
520         throw new NullPointerException("gratuitous throw!");
521     }
522 
misc()523     public void misc() {
524         System.out.println("misc");
525     }
526 
527     public int anInt;
528     public String string1 = "hey";
529     public String string2 = "yo";
530     public String string3 = "there";
531     private String string4 = "naughty";
532     public static final String constantString = "a constant string";
533     private int aPrivateInt;
534 
535     public final int cantTouchThis = 77;
536 
537     public long pubLong = 0x1122334455667788L;
538 
539     public static double staticDouble = 3.3;
540 }
541 
542 class NoisyInit {
543     static {
544         System.out.println("NoisyInit is initializing");
545         //Throwable th = new Throwable();
546         //th.printStackTrace();
547     }
548 }
549 
550 class NoisyInitUser {
551     static {
552         System.out.println("NoisyInitUser is initializing");
553     }
createNoisyInit(NoisyInit ni)554     public void createNoisyInit(NoisyInit ni) {}
555 }
556