blob: f6d9b68f4efe7c676a22beb1b33d6adbacd1d13c [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
jeffhao5d1ac922011-09-29 17:41:15 -070016
17import java.lang.reflect.*;
18import java.io.IOException;
19import java.util.Collections;
20
21/**
22 * Reflection test.
23 */
24public class Main {
25 void printMethodInfo(Method meth) {
26 Class[] params, exceptions;
27 int i;
28
29 System.out.println("Method name is " + meth.getName());
30 System.out.println(" Declaring class is "
31 + meth.getDeclaringClass().getName());
32 params = meth.getParameterTypes();
33 for (i = 0; i < params.length; i++)
34 System.out.println(" Arg " + i + ": " + params[i].getName());
35 exceptions = meth.getExceptionTypes();
36 for (i = 0; i < exceptions.length; i++)
37 System.out.println(" Exc " + i + ": " + exceptions[i].getName());
38 System.out.println(" Return type is " + meth.getReturnType().getName());
39 System.out.println(" Access flags are 0x"
40 + Integer.toHexString(meth.getModifiers()));
41 //System.out.println(" GenericStr is " + meth.toGenericString());
42 }
43
44 void printFieldInfo(Field field) {
45 System.out.println("Field name is " + field.getName());
46 System.out.println(" Declaring class is "
47 + field.getDeclaringClass().getName());
48 System.out.println(" Field type is " + field.getType().getName());
49 System.out.println(" Access flags are 0x"
50 + Integer.toHexString(field.getModifiers()));
51 }
52
53 private void showStrings(Target instance)
54 throws NoSuchFieldException, IllegalAccessException {
55
56 Class target = Target.class;
57 String one, two, three, four;
58 Field field = null;
59
60 field = target.getField("string1");
61 one = (String) field.get(instance);
62
63 field = target.getField("string2");
64 two = (String) field.get(instance);
65
66 field = target.getField("string3");
67 three = (String) field.get(instance);
68
69 System.out.println(" ::: " + one + ":" + two + ":" + three);
70 }
71
72 public void run() {
73 Class target = Target.class;
74 Method meth = null;
75 Field field = null;
76 boolean excep;
77
78 try {
79 meth = target.getMethod("myMethod", new Class[] { int.class });
80
81 if (meth.getDeclaringClass() != target)
82 throw new RuntimeException();
83 printMethodInfo(meth);
84
85 meth = target.getMethod("myMethod", new Class[] { float.class });
86 printMethodInfo(meth);
87
88 meth = target.getMethod("myNoargMethod", (Class[]) null);
89 printMethodInfo(meth);
90
91 meth = target.getMethod("myMethod",
92 new Class[] { String[].class, float.class, char.class });
93 printMethodInfo(meth);
94
95 Target instance = new Target();
96 Object[] argList = new Object[] {
97 new String[] { "hi there" },
98 new Float(3.1415926f),
99 new Character('Q')
100 };
101 System.out.println("Before, float is "
102 + ((Float)argList[1]).floatValue());
103
104 Integer boxval;
105 boxval = (Integer) meth.invoke(instance, argList);
106 System.out.println("Result of invoke: " + boxval.intValue());
107
108 System.out.println("Calling no-arg void-return method");
109 meth = target.getMethod("myNoargMethod", (Class[]) null);
110 meth.invoke(instance, (Object[]) null);
111
112 /* try invoking a method that throws an exception */
113 meth = target.getMethod("throwingMethod", (Class[]) null);
114 try {
115 meth.invoke(instance, (Object[]) null);
116 System.out.println("GLITCH: didn't throw");
117 } catch (InvocationTargetException ite) {
118 System.out.println("Invoke got expected exception:");
119 System.out.println(ite.getClass().getName());
120 System.out.println(ite.getCause());
121 }
122 catch (Exception ex) {
123 System.out.println("GLITCH: invoke got wrong exception:");
124 ex.printStackTrace();
125 }
126 System.out.println("");
127
128
129 field = target.getField("string1");
130 if (field.getDeclaringClass() != target)
131 throw new RuntimeException();
132 printFieldInfo(field);
133 String strVal = (String) field.get(instance);
134 System.out.println(" string1 value is '" + strVal + "'");
135
136 showStrings(instance);
137
138 field.set(instance, new String("a new string"));
139 strVal = (String) field.get(instance);
140 System.out.println(" string1 value is now '" + strVal + "'");
141
142 showStrings(instance);
143
144 try {
145 field.set(instance, new Object());
146 System.out.println("WARNING: able to store Object into String");
147 }
148 catch (IllegalArgumentException iae) {
149 System.out.println(" got expected illegal obj store exc");
150 }
151
152
153 try {
154 String four;
155 field = target.getField("string4");
156 four = (String) field.get(instance);
157 System.out.println("WARNING: able to access string4: "
158 + four);
159 }
160 catch (IllegalAccessException iae) {
161 System.out.println(" got expected access exc");
162 }
163 catch (NoSuchFieldException nsfe) {
164 System.out.println(" got the other expected access exc");
165 }
166 try {
167 String three;
168 field = target.getField("string3");
169 three = (String) field.get(this);
170 System.out.println("WARNING: able to get string3 in wrong obj: "
171 + three);
172 }
173 catch (IllegalArgumentException iae) {
174 System.out.println(" got expected arg exc");
175 }
176
177 /*
178 * Try setting a field to null.
179 */
180 String four;
181 field = target.getDeclaredField("string3");
182 field.set(instance, null);
183
184 /*
185 * Do some stuff with long.
186 */
187 long longVal;
188 field = target.getField("pubLong");
189 longVal = field.getLong(instance);
190 System.out.println("pubLong initial value is " +
191 Long.toHexString(longVal));
192 field.setLong(instance, 0x9988776655443322L);
193 longVal = field.getLong(instance);
194 System.out.println("pubLong new value is " +
195 Long.toHexString(longVal));
196
197
198 field = target.getField("superInt");
199 if (field.getDeclaringClass() == target)
200 throw new RuntimeException();
201 printFieldInfo(field);
202 int intVal = field.getInt(instance);
203 System.out.println(" superInt value is " + intVal);
204 Integer boxedIntVal = (Integer) field.get(instance);
205 System.out.println(" superInt boxed is " + boxedIntVal);
206
207 field.set(instance, new Integer(20202));
208 intVal = field.getInt(instance);
209 System.out.println(" superInt value is now " + intVal);
210 field.setShort(instance, (short)30303);
211 intVal = field.getInt(instance);
212 System.out.println(" superInt value (from short) is now " +intVal);
213 field.setInt(instance, 40404);
214 intVal = field.getInt(instance);
215 System.out.println(" superInt value is now " + intVal);
216 try {
217 field.set(instance, new Long(123));
218 System.out.println("FAIL: expected exception not thrown");
219 }
220 catch (IllegalArgumentException iae) {
221 System.out.println(" got expected long->int failure");
222 }
223 try {
224 field.setLong(instance, 123);
225 System.out.println("FAIL: expected exception not thrown");
226 }
227 catch (IllegalArgumentException iae) {
228 System.out.println(" got expected long->int failure");
229 }
230 try {
231 field.set(instance, new String("abc"));
232 System.out.println("FAIL: expected exception not thrown");
233 }
234 catch (IllegalArgumentException iae) {
235 System.out.println(" got expected string->int failure");
236 }
237
238 try {
239 field.getShort(instance);
240 System.out.println("FAIL: expected exception not thrown");
241 }
242 catch (IllegalArgumentException iae) {
243 System.out.println(" got expected int->short failure");
244 }
245
246 field = target.getField("superClassInt");
247 printFieldInfo(field);
248 int superClassIntVal = field.getInt(instance);
249 System.out.println(" superClassInt value is " + superClassIntVal);
250
251 field = target.getField("staticDouble");
252 printFieldInfo(field);
253 double staticDoubleVal = field.getDouble(null);
254 System.out.println(" staticDoubleVal value is " + staticDoubleVal);
255
256 try {
257 field.getLong(instance);
258 System.out.println("FAIL: expected exception not thrown");
259 }
260 catch (IllegalArgumentException iae) {
261 System.out.println(" got expected double->long failure");
262 }
263
264 excep = false;
265 try {
266 field = target.getField("aPrivateInt");
267 printFieldInfo(field);
268 }
269 catch (NoSuchFieldException nsfe) {
270 System.out.println("as expected: aPrivateInt not found");
271 excep = true;
272 }
273 if (!excep)
274 System.out.println("BUG: got aPrivateInt");
275
276
277 field = target.getField("constantString");
278 printFieldInfo(field);
279 String val = (String) field.get(instance);
280 System.out.println(" Constant test value is " + val);
281
282
283 field = target.getField("cantTouchThis");
284 printFieldInfo(field);
285 intVal = field.getInt(instance);
286 System.out.println(" cantTouchThis is " + intVal);
287 try {
288 field.setInt(instance, 99);
Elliott Hughes582a7d12011-10-10 18:38:42 -0700289 System.out.println(" setAccessible is always true");
jeffhao5d1ac922011-09-29 17:41:15 -0700290 } catch (IllegalAccessException iae) {
Elliott Hughes582a7d12011-10-10 18:38:42 -0700291 System.out.println("ERROR: set-final failed");
jeffhao5d1ac922011-09-29 17:41:15 -0700292 }
293 intVal = field.getInt(instance);
294 System.out.println(" cantTouchThis is now " + intVal);
295
296 field.setAccessible(true);
297 field.setInt(instance, 87); // exercise int version
Elliott Hughes582a7d12011-10-10 18:38:42 -0700298 intVal = field.getInt(instance);
299 System.out.println(" cantTouchThis is now " + intVal);
jeffhao5d1ac922011-09-29 17:41:15 -0700300 field.set(instance, 88); // exercise Object version
301 intVal = field.getInt(instance);
302 System.out.println(" cantTouchThis is now " + intVal);
303
304 Constructor<Target> cons;
305 Target targ;
306 Object[] args;
307
308 cons = target.getConstructor(new Class[] { int.class,float.class });
309 args = new Object[] { new Integer(7), new Float(3.3333) };
310 System.out.println("cons modifiers=" + cons.getModifiers());
311 targ = cons.newInstance(args);
312 targ.myMethod(17);
313
314 }
315 catch (Exception ex) {
316 System.out.println("----- unexpected exception -----");
317 ex.printStackTrace();
318 }
319
320 System.out.println("ReflectTest done!");
321 }
322
323 public static void checkType() {
324 Method m;
325
326 try {
327 m = Collections.class.getDeclaredMethod("checkType",
328 Object.class, Class.class);
329 } catch (NoSuchMethodException nsme) {
330 nsme.printStackTrace();
331 return;
332 }
333
334 m.setAccessible(true);
335 try {
336 m.invoke(null, new Object(), Object.class);
337 } catch (IllegalAccessException iae) {
338 iae.printStackTrace();
339 return;
340 } catch (InvocationTargetException ite) {
341 ite.printStackTrace();
342 return;
343 }
344
345 try {
346 System.out.println("checkType invoking null");
347 m.invoke(null, new Object(), int.class);
348 System.out.println("ERROR: should throw InvocationTargetException");
349 } catch (InvocationTargetException ite) {
350 System.out.println("checkType got expected exception");
351 } catch (IllegalAccessException iae) {
352 iae.printStackTrace();
353 return;
354 }
355 }
356
357 public static void checkInit() {
Elliott Hughesf3778f62012-01-26 14:14:35 -0800358 System.out.println("calling const-class NoisyInitUser.class");
359 Class niuClass = NoisyInitUser.class;
360 System.out.println("called const-class NoisyInitUser.class");
361 Method[] methods;
jeffhao5d1ac922011-09-29 17:41:15 -0700362
363 methods = niuClass.getDeclaredMethods();
364 System.out.println("got methods");
365 /* neither NoisyInit nor NoisyInitUser should be initialized yet */
366 NoisyInitUser niu = new NoisyInitUser();
367 NoisyInit ni = new NoisyInit();
368 }
369
370 public static void main(String[] args) {
371 Main test = new Main();
372 test.run();
373
374 checkType();
375 checkInit();
376 }
377}
378
379
380class SuperTarget {
381 public SuperTarget() {
382 System.out.println("SuperTarget constructor ()V");
383 superInt = 1010101;
384 superClassInt = 1010102;
385 }
386
387 public int myMethod(float floatArg) {
388 System.out.println("myMethod (F)I " + floatArg);
389 return 6;
390 }
391
392 public int superInt;
393 public static int superClassInt;
394}
395
396class Target extends SuperTarget {
397 public Target() {
398 System.out.println("Target constructor ()V");
399 }
400
401 public Target(int ii, float ff) {
402 System.out.println("Target constructor (IF)V : ii="
403 + ii + " ff=" + ff);
404 anInt = ii;
405 }
406
407 public int myMethod(int intarg) throws NullPointerException, IOException {
408 System.out.println("myMethod (I)I");
409 System.out.println(" arg=" + intarg + " anInt=" + anInt);
410 return 5;
411 }
412
413 public int myMethod(String[] strarg, float f, char c) {
414 System.out.println("myMethod: " + strarg[0] + " " + f + " " + c + " !");
415 return 7;
416 }
417
418 public static void myNoargMethod() {
419 System.out.println("myNoargMethod ()V");
420 }
421
422 public void throwingMethod() {
423 System.out.println("throwingMethod");
424 throw new NullPointerException("gratuitous throw!");
425 }
426
427 public void misc() {
428 System.out.println("misc");
429 }
430
431 public int anInt;
432 public String string1 = "hey";
433 public String string2 = "yo";
434 public String string3 = "there";
435 private String string4 = "naughty";
436 public static final String constantString = "a constant string";
437 private int aPrivateInt;
438
439 public final int cantTouchThis = 77;
440
441 public long pubLong = 0x1122334455667788L;
442
443 public static double staticDouble = 3.3;
444}
445
446class NoisyInit {
447 static {
448 System.out.println("NoisyInit is initializing");
449 //Throwable th = new Throwable();
450 //th.printStackTrace();
451 }
452}
453
454class NoisyInitUser {
455 static {
456 System.out.println("NoisyInitUser is initializing");
457 }
458 public void createNoisyInit(NoisyInit ni) {}
459}