blob: 10dad8ddacb9de22f017ce85146607f2af415655 [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;
Elliott Hughes741b5b72012-01-31 19:18:51 -080020import java.util.ArrayList;
Piotr Jastrzebski68b539e2014-08-06 12:02:48 +010021import java.util.Arrays;
Elliott Hughes741b5b72012-01-31 19:18:51 -080022import java.util.List;
23import java.util.Map;
Piotr Jastrzebski68b539e2014-08-06 12:02:48 +010024import java.util.Set;
jeffhao5d1ac922011-09-29 17:41:15 -070025
26/**
27 * Reflection test.
28 */
29public class Main {
Elliott Hughes741b5b72012-01-31 19:18:51 -080030 private static boolean FULL_ACCESS_CHECKS = false; // b/5861201
31 public Main() {}
32 public Main(ArrayList<Integer> stuff) {}
33
jeffhao5d1ac922011-09-29 17:41:15 -070034 void printMethodInfo(Method meth) {
Andreas Gampe166aaee2016-07-18 08:27:23 -070035 Class<?>[] params, exceptions;
jeffhao5d1ac922011-09-29 17:41:15 -070036 int i;
37
38 System.out.println("Method name is " + meth.getName());
39 System.out.println(" Declaring class is "
40 + meth.getDeclaringClass().getName());
41 params = meth.getParameterTypes();
42 for (i = 0; i < params.length; i++)
43 System.out.println(" Arg " + i + ": " + params[i].getName());
44 exceptions = meth.getExceptionTypes();
45 for (i = 0; i < exceptions.length; i++)
46 System.out.println(" Exc " + i + ": " + exceptions[i].getName());
47 System.out.println(" Return type is " + meth.getReturnType().getName());
48 System.out.println(" Access flags are 0x"
49 + Integer.toHexString(meth.getModifiers()));
50 //System.out.println(" GenericStr is " + meth.toGenericString());
51 }
52
53 void printFieldInfo(Field field) {
54 System.out.println("Field name is " + field.getName());
55 System.out.println(" Declaring class is "
56 + field.getDeclaringClass().getName());
57 System.out.println(" Field type is " + field.getType().getName());
58 System.out.println(" Access flags are 0x"
59 + Integer.toHexString(field.getModifiers()));
60 }
61
62 private void showStrings(Target instance)
63 throws NoSuchFieldException, IllegalAccessException {
64
Andreas Gampe166aaee2016-07-18 08:27:23 -070065 Class<?> target = Target.class;
jeffhao5d1ac922011-09-29 17:41:15 -070066 String one, two, three, four;
67 Field field = null;
68
69 field = target.getField("string1");
70 one = (String) field.get(instance);
71
72 field = target.getField("string2");
73 two = (String) field.get(instance);
74
75 field = target.getField("string3");
76 three = (String) field.get(instance);
77
78 System.out.println(" ::: " + one + ":" + two + ":" + three);
79 }
80
Elliott Hughes741b5b72012-01-31 19:18:51 -080081 public static void checkAccess() {
82 try {
Andreas Gampe166aaee2016-07-18 08:27:23 -070083 Class<?> target = otherpackage.Other.class;
Elliott Hughes741b5b72012-01-31 19:18:51 -080084 Object instance = new otherpackage.Other();
85 Method meth;
86
Andreas Gampe166aaee2016-07-18 08:27:23 -070087 meth = target.getMethod("publicMethod");
Elliott Hughes741b5b72012-01-31 19:18:51 -080088 meth.invoke(instance);
89
90 try {
Andreas Gampe166aaee2016-07-18 08:27:23 -070091 meth = target.getMethod("packageMethod");
Elliott Hughes741b5b72012-01-31 19:18:51 -080092 System.err.println("succeeded on package-scope method");
93 } catch (NoSuchMethodException nsme) {
94 // good
95 }
96
97
98 instance = otherpackage.Other.getInnerClassInstance();
99 target = instance.getClass();
Andreas Gampe166aaee2016-07-18 08:27:23 -0700100 meth = target.getMethod("innerMethod");
Elliott Hughes741b5b72012-01-31 19:18:51 -0800101 try {
102 if (!FULL_ACCESS_CHECKS) { throw new IllegalAccessException(); }
103 meth.invoke(instance);
104 System.err.println("inner-method invoke unexpectedly worked");
105 } catch (IllegalAccessException iae) {
106 // good
107 }
108
109 Field field = target.getField("innerField");
110 try {
111 int x = field.getInt(instance);
112 if (!FULL_ACCESS_CHECKS) { throw new IllegalAccessException(); }
113 System.err.println("field get unexpectedly worked: " + x);
114 } catch (IllegalAccessException iae) {
115 // good
116 }
117 } catch (Exception ex) {
118 System.out.println("----- unexpected exception -----");
119 ex.printStackTrace();
120 }
121 }
122
jeffhao5d1ac922011-09-29 17:41:15 -0700123 public void run() {
Andreas Gampe166aaee2016-07-18 08:27:23 -0700124 Class<Target> target = Target.class;
jeffhao5d1ac922011-09-29 17:41:15 -0700125 Method meth = null;
126 Field field = null;
127 boolean excep;
128
129 try {
Andreas Gampe166aaee2016-07-18 08:27:23 -0700130 meth = target.getMethod("myMethod", int.class);
jeffhao5d1ac922011-09-29 17:41:15 -0700131
132 if (meth.getDeclaringClass() != target)
133 throw new RuntimeException();
134 printMethodInfo(meth);
135
Andreas Gampe166aaee2016-07-18 08:27:23 -0700136 meth = target.getMethod("myMethod", float.class);
jeffhao5d1ac922011-09-29 17:41:15 -0700137 printMethodInfo(meth);
138
Andreas Gampe166aaee2016-07-18 08:27:23 -0700139 meth = target.getMethod("myNoargMethod");
jeffhao5d1ac922011-09-29 17:41:15 -0700140 printMethodInfo(meth);
141
Andreas Gampe166aaee2016-07-18 08:27:23 -0700142 meth = target.getMethod("myMethod", String[].class, float.class, char.class);
jeffhao5d1ac922011-09-29 17:41:15 -0700143 printMethodInfo(meth);
144
145 Target instance = new Target();
146 Object[] argList = new Object[] {
147 new String[] { "hi there" },
148 new Float(3.1415926f),
Fredrik Roubertaf50e412015-07-28 00:14:08 +0200149 new Character('\u2714')
jeffhao5d1ac922011-09-29 17:41:15 -0700150 };
151 System.out.println("Before, float is "
152 + ((Float)argList[1]).floatValue());
153
154 Integer boxval;
155 boxval = (Integer) meth.invoke(instance, argList);
156 System.out.println("Result of invoke: " + boxval.intValue());
157
158 System.out.println("Calling no-arg void-return method");
Andreas Gampe166aaee2016-07-18 08:27:23 -0700159 meth = target.getMethod("myNoargMethod");
jeffhao5d1ac922011-09-29 17:41:15 -0700160 meth.invoke(instance, (Object[]) null);
161
162 /* try invoking a method that throws an exception */
Andreas Gampe166aaee2016-07-18 08:27:23 -0700163 meth = target.getMethod("throwingMethod");
jeffhao5d1ac922011-09-29 17:41:15 -0700164 try {
165 meth.invoke(instance, (Object[]) null);
166 System.out.println("GLITCH: didn't throw");
167 } catch (InvocationTargetException ite) {
168 System.out.println("Invoke got expected exception:");
169 System.out.println(ite.getClass().getName());
170 System.out.println(ite.getCause());
171 }
172 catch (Exception ex) {
173 System.out.println("GLITCH: invoke got wrong exception:");
174 ex.printStackTrace();
175 }
176 System.out.println("");
177
178
179 field = target.getField("string1");
180 if (field.getDeclaringClass() != target)
181 throw new RuntimeException();
182 printFieldInfo(field);
183 String strVal = (String) field.get(instance);
184 System.out.println(" string1 value is '" + strVal + "'");
185
186 showStrings(instance);
187
188 field.set(instance, new String("a new string"));
189 strVal = (String) field.get(instance);
190 System.out.println(" string1 value is now '" + strVal + "'");
191
192 showStrings(instance);
193
194 try {
195 field.set(instance, new Object());
196 System.out.println("WARNING: able to store Object into String");
197 }
198 catch (IllegalArgumentException iae) {
199 System.out.println(" got expected illegal obj store exc");
200 }
201
202
203 try {
204 String four;
205 field = target.getField("string4");
206 four = (String) field.get(instance);
207 System.out.println("WARNING: able to access string4: "
208 + four);
209 }
210 catch (IllegalAccessException iae) {
211 System.out.println(" got expected access exc");
212 }
213 catch (NoSuchFieldException nsfe) {
214 System.out.println(" got the other expected access exc");
215 }
216 try {
217 String three;
218 field = target.getField("string3");
219 three = (String) field.get(this);
220 System.out.println("WARNING: able to get string3 in wrong obj: "
221 + three);
222 }
223 catch (IllegalArgumentException iae) {
224 System.out.println(" got expected arg exc");
225 }
226
227 /*
228 * Try setting a field to null.
229 */
230 String four;
231 field = target.getDeclaredField("string3");
232 field.set(instance, null);
233
234 /*
Mathieu Chartier3beb2452015-05-13 13:13:24 -0700235 * Try getDeclaredField on a non-existant field.
236 */
237 try {
238 field = target.getDeclaredField("nonExistant");
239 System.out.println("ERROR: Expected NoSuchFieldException");
240 } catch (NoSuchFieldException nsfe) {
241 String msg = nsfe.getMessage();
242 if (!msg.contains("Target;")) {
243 System.out.println(" NoSuchFieldException '" + msg +
244 "' didn't contain class");
245 }
246 }
247
248 /*
jeffhao5d1ac922011-09-29 17:41:15 -0700249 * Do some stuff with long.
250 */
251 long longVal;
252 field = target.getField("pubLong");
253 longVal = field.getLong(instance);
254 System.out.println("pubLong initial value is " +
255 Long.toHexString(longVal));
256 field.setLong(instance, 0x9988776655443322L);
257 longVal = field.getLong(instance);
258 System.out.println("pubLong new value is " +
259 Long.toHexString(longVal));
260
261
262 field = target.getField("superInt");
263 if (field.getDeclaringClass() == target)
264 throw new RuntimeException();
265 printFieldInfo(field);
266 int intVal = field.getInt(instance);
267 System.out.println(" superInt value is " + intVal);
268 Integer boxedIntVal = (Integer) field.get(instance);
269 System.out.println(" superInt boxed is " + boxedIntVal);
270
271 field.set(instance, new Integer(20202));
272 intVal = field.getInt(instance);
273 System.out.println(" superInt value is now " + intVal);
274 field.setShort(instance, (short)30303);
275 intVal = field.getInt(instance);
276 System.out.println(" superInt value (from short) is now " +intVal);
277 field.setInt(instance, 40404);
278 intVal = field.getInt(instance);
279 System.out.println(" superInt value is now " + intVal);
280 try {
281 field.set(instance, new Long(123));
282 System.out.println("FAIL: expected exception not thrown");
283 }
284 catch (IllegalArgumentException iae) {
285 System.out.println(" got expected long->int failure");
286 }
287 try {
288 field.setLong(instance, 123);
289 System.out.println("FAIL: expected exception not thrown");
290 }
291 catch (IllegalArgumentException iae) {
292 System.out.println(" got expected long->int failure");
293 }
294 try {
295 field.set(instance, new String("abc"));
296 System.out.println("FAIL: expected exception not thrown");
297 }
298 catch (IllegalArgumentException iae) {
299 System.out.println(" got expected string->int failure");
300 }
301
302 try {
303 field.getShort(instance);
304 System.out.println("FAIL: expected exception not thrown");
305 }
306 catch (IllegalArgumentException iae) {
307 System.out.println(" got expected int->short failure");
308 }
309
310 field = target.getField("superClassInt");
311 printFieldInfo(field);
312 int superClassIntVal = field.getInt(instance);
313 System.out.println(" superClassInt value is " + superClassIntVal);
314
315 field = target.getField("staticDouble");
316 printFieldInfo(field);
317 double staticDoubleVal = field.getDouble(null);
318 System.out.println(" staticDoubleVal value is " + staticDoubleVal);
319
320 try {
321 field.getLong(instance);
322 System.out.println("FAIL: expected exception not thrown");
323 }
324 catch (IllegalArgumentException iae) {
325 System.out.println(" got expected double->long failure");
326 }
327
328 excep = false;
329 try {
330 field = target.getField("aPrivateInt");
331 printFieldInfo(field);
332 }
333 catch (NoSuchFieldException nsfe) {
334 System.out.println("as expected: aPrivateInt not found");
335 excep = true;
336 }
337 if (!excep)
338 System.out.println("BUG: got aPrivateInt");
339
340
341 field = target.getField("constantString");
342 printFieldInfo(field);
343 String val = (String) field.get(instance);
344 System.out.println(" Constant test value is " + val);
345
346
347 field = target.getField("cantTouchThis");
348 printFieldInfo(field);
349 intVal = field.getInt(instance);
350 System.out.println(" cantTouchThis is " + intVal);
351 try {
352 field.setInt(instance, 99);
Jeff Hao11d5d8f2014-03-26 15:08:20 -0700353 System.out.println("ERROR: set-final did not throw exception");
jeffhao5d1ac922011-09-29 17:41:15 -0700354 } catch (IllegalAccessException iae) {
Jeff Hao11d5d8f2014-03-26 15:08:20 -0700355 System.out.println(" as expected: set-final throws exception");
jeffhao5d1ac922011-09-29 17:41:15 -0700356 }
357 intVal = field.getInt(instance);
Jeff Hao11d5d8f2014-03-26 15:08:20 -0700358 System.out.println(" cantTouchThis is still " + intVal);
jeffhao5d1ac922011-09-29 17:41:15 -0700359
Brian Carlstromea46f952013-07-30 01:26:50 -0700360 System.out.println(" " + field + " accessible=" + field.isAccessible());
jeffhao5d1ac922011-09-29 17:41:15 -0700361 field.setAccessible(true);
Brian Carlstromea46f952013-07-30 01:26:50 -0700362 System.out.println(" " + field + " accessible=" + field.isAccessible());
jeffhao5d1ac922011-09-29 17:41:15 -0700363 field.setInt(instance, 87); // exercise int version
Elliott Hughes582a7d12011-10-10 18:38:42 -0700364 intVal = field.getInt(instance);
365 System.out.println(" cantTouchThis is now " + intVal);
jeffhao5d1ac922011-09-29 17:41:15 -0700366 field.set(instance, 88); // exercise Object version
367 intVal = field.getInt(instance);
368 System.out.println(" cantTouchThis is now " + intVal);
369
370 Constructor<Target> cons;
371 Target targ;
372 Object[] args;
373
Andreas Gampe166aaee2016-07-18 08:27:23 -0700374 cons = target.getConstructor(int.class, float.class);
jeffhao5d1ac922011-09-29 17:41:15 -0700375 args = new Object[] { new Integer(7), new Float(3.3333) };
376 System.out.println("cons modifiers=" + cons.getModifiers());
377 targ = cons.newInstance(args);
378 targ.myMethod(17);
379
Jeff Hao63f5b9e2014-04-23 14:51:46 -0700380 try {
381 Thrower thrower = Thrower.class.newInstance();
382 System.out.println("ERROR: Class.newInstance did not throw exception");
383 } catch (UnsupportedOperationException uoe) {
384 System.out.println("got expected exception for Class.newInstance");
385 } catch (Exception e) {
386 System.out.println("ERROR: Class.newInstance got unexpected exception: " +
387 e.getClass().getName());
388 }
389
390 try {
391 Constructor<Thrower> constructor = Thrower.class.getDeclaredConstructor();
392 Thrower thrower = constructor.newInstance();
393 System.out.println("ERROR: Constructor.newInstance did not throw exception");
394 } catch (InvocationTargetException ite) {
395 System.out.println("got expected exception for Constructor.newInstance");
396 } catch (Exception e) {
397 System.out.println("ERROR: Constructor.newInstance got unexpected exception: " +
398 e.getClass().getName());
399 }
400
Elliott Hughes741b5b72012-01-31 19:18:51 -0800401 } catch (Exception ex) {
jeffhao5d1ac922011-09-29 17:41:15 -0700402 System.out.println("----- unexpected exception -----");
403 ex.printStackTrace();
404 }
405
406 System.out.println("ReflectTest done!");
407 }
408
Narayan Kamath3778c872015-11-17 13:46:30 +0000409 public static void checkSwap() {
jeffhao5d1ac922011-09-29 17:41:15 -0700410 Method m;
411
Narayan Kamath3778c872015-11-17 13:46:30 +0000412 final Object[] objects = new Object[2];
jeffhao5d1ac922011-09-29 17:41:15 -0700413 try {
Narayan Kamath3778c872015-11-17 13:46:30 +0000414 m = Collections.class.getDeclaredMethod("swap",
415 Object[].class, int.class, int.class);
jeffhao5d1ac922011-09-29 17:41:15 -0700416 } catch (NoSuchMethodException nsme) {
417 nsme.printStackTrace();
418 return;
419 }
Brian Carlstromea46f952013-07-30 01:26:50 -0700420 System.out.println(m + " accessible=" + m.isAccessible());
jeffhao5d1ac922011-09-29 17:41:15 -0700421 m.setAccessible(true);
Brian Carlstromea46f952013-07-30 01:26:50 -0700422 System.out.println(m + " accessible=" + m.isAccessible());
jeffhao5d1ac922011-09-29 17:41:15 -0700423 try {
Narayan Kamath3778c872015-11-17 13:46:30 +0000424 m.invoke(null, objects, 0, 1);
jeffhao5d1ac922011-09-29 17:41:15 -0700425 } catch (IllegalAccessException iae) {
426 iae.printStackTrace();
427 return;
428 } catch (InvocationTargetException ite) {
429 ite.printStackTrace();
430 return;
431 }
432
433 try {
Jeff Hao7a549462013-03-18 19:04:24 -0700434 String s = "Should be ignored";
Narayan Kamath3778c872015-11-17 13:46:30 +0000435 m.invoke(s, objects, 0, 1);
Jeff Hao7a549462013-03-18 19:04:24 -0700436 } catch (IllegalAccessException iae) {
437 iae.printStackTrace();
438 return;
439 } catch (InvocationTargetException ite) {
440 ite.printStackTrace();
441 return;
442 }
443
444 try {
jeffhao5d1ac922011-09-29 17:41:15 -0700445 System.out.println("checkType invoking null");
Narayan Kamath3778c872015-11-17 13:46:30 +0000446 // Trigger an NPE at the target.
447 m.invoke(null, null, 0, 1);
jeffhao5d1ac922011-09-29 17:41:15 -0700448 System.out.println("ERROR: should throw InvocationTargetException");
449 } catch (InvocationTargetException ite) {
450 System.out.println("checkType got expected exception");
451 } catch (IllegalAccessException iae) {
452 iae.printStackTrace();
453 return;
454 }
455 }
456
Elliott Hughes923e8b82012-03-23 11:44:07 -0700457 public static void checkClinitForFields() throws Exception {
458 // Loading a class constant shouldn't run <clinit>.
459 System.out.println("calling const-class FieldNoisyInitUser.class");
Andreas Gampe166aaee2016-07-18 08:27:23 -0700460 Class<?> niuClass = FieldNoisyInitUser.class;
Elliott Hughes923e8b82012-03-23 11:44:07 -0700461 System.out.println("called const-class FieldNoisyInitUser.class");
jeffhao5d1ac922011-09-29 17:41:15 -0700462
Elliott Hughes923e8b82012-03-23 11:44:07 -0700463 // Getting the declared fields doesn't run <clinit>.
464 Field[] fields = niuClass.getDeclaredFields();
465 System.out.println("got fields");
Elliott Hughes741b5b72012-01-31 19:18:51 -0800466
Elliott Hughes923e8b82012-03-23 11:44:07 -0700467 Field field = niuClass.getField("staticField");
468 System.out.println("got field");
469 field.get(null);
470 System.out.println("read field value");
471
472 // FieldNoisyInitUser should now be initialized, but FieldNoisyInit shouldn't be initialized yet.
473 FieldNoisyInitUser niu = new FieldNoisyInitUser();
474 FieldNoisyInit ni = new FieldNoisyInit();
475
476 System.out.println("");
477 }
478
479 public static void checkClinitForMethods() throws Exception {
480 // Loading a class constant shouldn't run <clinit>.
481 System.out.println("calling const-class MethodNoisyInitUser.class");
Andreas Gampe166aaee2016-07-18 08:27:23 -0700482 Class<?> niuClass = MethodNoisyInitUser.class;
Elliott Hughes923e8b82012-03-23 11:44:07 -0700483 System.out.println("called const-class MethodNoisyInitUser.class");
484
485 // Getting the declared methods doesn't run <clinit>.
486 Method[] methods = niuClass.getDeclaredMethods();
487 System.out.println("got methods");
488
Andreas Gampe166aaee2016-07-18 08:27:23 -0700489 Method method = niuClass.getMethod("staticMethod");
Elliott Hughes923e8b82012-03-23 11:44:07 -0700490 System.out.println("got method");
491 method.invoke(null);
492 System.out.println("invoked method");
493
494 // MethodNoisyInitUser should now be initialized, but MethodNoisyInit shouldn't be initialized yet.
495 MethodNoisyInitUser niu = new MethodNoisyInitUser();
496 MethodNoisyInit ni = new MethodNoisyInit();
497
498 System.out.println("");
jeffhao5d1ac922011-09-29 17:41:15 -0700499 }
500
Elliott Hughes741b5b72012-01-31 19:18:51 -0800501
502 /*
503 * Test some generic type stuff.
504 */
505 public List<String> dummy;
506 public Map<Integer,String> fancyMethod(ArrayList<String> blah) { return null; }
507 public static void checkGeneric() {
508 Field field;
509 try {
510 field = Main.class.getField("dummy");
511 } catch (NoSuchFieldException nsfe) {
512 throw new RuntimeException(nsfe);
513 }
514 Type listType = field.getGenericType();
515 System.out.println("generic field: " + listType);
516
517 Method method;
518 try {
Andreas Gampe166aaee2016-07-18 08:27:23 -0700519 method = Main.class.getMethod("fancyMethod", ArrayList.class);
Elliott Hughes741b5b72012-01-31 19:18:51 -0800520 } catch (NoSuchMethodException nsme) {
521 throw new RuntimeException(nsme);
522 }
523 Type[] parmTypes = method.getGenericParameterTypes();
524 Type ret = method.getGenericReturnType();
525 System.out.println("generic method " + method.getName() + " params='"
526 + stringifyTypeArray(parmTypes) + "' ret='" + ret + "'");
527
Andreas Gampe166aaee2016-07-18 08:27:23 -0700528 Constructor<?> ctor;
Elliott Hughes741b5b72012-01-31 19:18:51 -0800529 try {
Andreas Gampe166aaee2016-07-18 08:27:23 -0700530 ctor = Main.class.getConstructor( ArrayList.class);
Elliott Hughes741b5b72012-01-31 19:18:51 -0800531 } catch (NoSuchMethodException nsme) {
532 throw new RuntimeException(nsme);
533 }
534 parmTypes = ctor.getGenericParameterTypes();
535 System.out.println("generic ctor " + ctor.getName() + " params='"
536 + stringifyTypeArray(parmTypes) + "'");
537 }
538
539 /*
540 * Convert an array of Type into a string. Start with an array count.
541 */
542 private static String stringifyTypeArray(Type[] types) {
543 StringBuilder stb = new StringBuilder();
544 boolean first = true;
545
546 stb.append("[" + types.length + "]");
547
548 for (Type t: types) {
549 if (first) {
550 stb.append(" ");
551 first = false;
552 } else {
553 stb.append(", ");
554 }
555 stb.append(t.toString());
556 }
557
558 return stb.toString();
559 }
560
Brian Carlstromea46f952013-07-30 01:26:50 -0700561 public static void checkUnique() {
562 Field field1, field2;
563 try {
564 field1 = Main.class.getField("dummy");
565 field2 = Main.class.getField("dummy");
566 } catch (NoSuchFieldException nsfe) {
567 throw new RuntimeException(nsfe);
568 }
569 if (field1 == field2) {
570 System.out.println("ERROR: fields shouldn't have reference equality");
571 } else {
572 System.out.println("fields are unique");
573 }
574 if (field1.hashCode() == field2.hashCode() && field1.equals(field2)) {
575 System.out.println("fields are .equals");
576 } else {
577 System.out.println("ERROR: fields fail equality");
578 }
579 Method method1, method2;
580 try {
Andreas Gampe166aaee2016-07-18 08:27:23 -0700581 method1 = Main.class.getMethod("fancyMethod", ArrayList.class);
582 method2 = Main.class.getMethod("fancyMethod", ArrayList.class);
Brian Carlstromea46f952013-07-30 01:26:50 -0700583 } catch (NoSuchMethodException nsme) {
584 throw new RuntimeException(nsme);
585 }
586 if (method1 == method2) {
587 System.out.println("ERROR: methods shouldn't have reference equality");
588 } else {
589 System.out.println("methods are unique");
590 }
591 if (method1.hashCode() == method2.hashCode() && method1.equals(method2)) {
592 System.out.println("methods are .equals");
593 } else {
594 System.out.println("ERROR: methods fail equality");
595 }
596 }
Elliott Hughes741b5b72012-01-31 19:18:51 -0800597
Piotr Jastrzebski68b539e2014-08-06 12:02:48 +0100598 public static void checkParametrizedTypeEqualsAndHashCode() {
599 Method method1;
600 Method method2;
601 Method method3;
602 try {
603 method1 = ParametrizedTypeTest.class.getDeclaredMethod("aMethod", Set.class);
604 method2 = ParametrizedTypeTest.class.getDeclaredMethod("aMethod", Set.class);
605 method3 = ParametrizedTypeTest.class.getDeclaredMethod("aMethodIdentical", Set.class);
606 } catch (NoSuchMethodException nsme) {
607 throw new RuntimeException(nsme);
608 }
609
610 List<Type> types1 = Arrays.asList(method1.getGenericParameterTypes());
611 List<Type> types2 = Arrays.asList(method2.getGenericParameterTypes());
612 List<Type> types3 = Arrays.asList(method3.getGenericParameterTypes());
613
614 Type type1 = types1.get(0);
615 Type type2 = types2.get(0);
616 Type type3 = types3.get(0);
617
618 if (type1 instanceof ParameterizedType) {
619 System.out.println("type1 is a ParameterizedType");
620 }
621 if (type2 instanceof ParameterizedType) {
622 System.out.println("type2 is a ParameterizedType");
623 }
624 if (type3 instanceof ParameterizedType) {
625 System.out.println("type3 is a ParameterizedType");
626 }
627
628 if (type1.equals(type2)) {
629 System.out.println("type1("+type1+") equals type2("+type2+")");
630 } else {
631 System.out.println("type1("+type1+") does not equal type2("+type2+")");
632 }
633
634 if (type1.equals(type3)) {
635 System.out.println("type1("+type1+") equals type3("+type3+")");
636 } else {
637 System.out.println("type1("+type1+") does not equal type3("+type3+")");
638 }
639 if (type1.hashCode() == type2.hashCode()) {
640 System.out.println("type1("+type1+") hashCode equals type2("+type2+") hashCode");
641 } else {
642 System.out.println(
643 "type1("+type1+") hashCode does not equal type2("+type2+") hashCode");
644 }
645
646 if (type1.hashCode() == type3.hashCode()) {
647 System.out.println("type1("+type1+") hashCode equals type3("+type3+") hashCode");
648 } else {
649 System.out.println(
650 "type1("+type1+") hashCode does not equal type3("+type3+") hashCode");
651 }
652 }
653
654 public static void checkGenericArrayTypeEqualsAndHashCode() {
655 Method method1;
656 Method method2;
657 Method method3;
658 try {
659 method1 = GenericArrayTypeTest.class.getDeclaredMethod("aMethod", Object[].class);
660 method2 = GenericArrayTypeTest.class.getDeclaredMethod("aMethod", Object[].class);
661 method3 = GenericArrayTypeTest.class.getDeclaredMethod("aMethodIdentical", Object[].class);
662 } catch (NoSuchMethodException nsme) {
663 throw new RuntimeException(nsme);
664 }
665
666 List<Type> types1 = Arrays.asList(method1.getGenericParameterTypes());
667 List<Type> types2 = Arrays.asList(method2.getGenericParameterTypes());
668 List<Type> types3 = Arrays.asList(method3.getGenericParameterTypes());
669
670 Type type1 = types1.get(0);
671 Type type2 = types2.get(0);
672 Type type3 = types3.get(0);
673
674 if (type1 instanceof GenericArrayType) {
675 System.out.println("type1 is a GenericArrayType");
676 }
677 if (type2 instanceof GenericArrayType) {
678 System.out.println("type2 is a GenericArrayType");
679 }
680 if (type3 instanceof GenericArrayType) {
681 System.out.println("type3 is a GenericArrayType");
682 }
683
684 if (type1.equals(type2)) {
685 System.out.println("type1("+type1+") equals type2("+type2+")");
686 } else {
687 System.out.println("type1("+type1+") does not equal type2("+type2+")");
688 }
689
690 if (type1.equals(type3)) {
691 System.out.println("type1("+type1+") equals type3("+type3+")");
692 } else {
693 System.out.println("type1("+type1+") does not equal type3("+type3+")");
694 }
695 if (type1.hashCode() == type2.hashCode()) {
696 System.out.println("type1("+type1+") hashCode equals type2("+type2+") hashCode");
697 } else {
698 System.out.println(
699 "type1("+type1+") hashCode does not equal type2("+type2+") hashCode");
700 }
701
702 if (type1.hashCode() == type3.hashCode()) {
703 System.out.println("type1("+type1+") hashCode equals type3("+type3+") hashCode");
704 } else {
705 System.out.println(
706 "type1("+type1+") hashCode does not equal type3("+type3+") hashCode");
707 }
708 }
709
Mathieu Chartier3ed4c542014-08-08 15:10:11 -0700710 private static void checkGetDeclaredConstructor() {
711 try {
712 Method.class.getDeclaredConstructor().setAccessible(true);
Narayan Kamath3778c872015-11-17 13:46:30 +0000713 System.out.println("Didn't get an exception from Method.class.getDeclaredConstructor().setAccessible");
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700714 } catch (SecurityException e) {
Mathieu Chartier3ed4c542014-08-08 15:10:11 -0700715 } catch (NoSuchMethodException e) {
716 } catch (Exception e) {
Narayan Kamath3778c872015-11-17 13:46:30 +0000717 System.out.println(e);
Mathieu Chartier3ed4c542014-08-08 15:10:11 -0700718 }
719 try {
720 Field.class.getDeclaredConstructor().setAccessible(true);
Narayan Kamath3778c872015-11-17 13:46:30 +0000721 System.out.println("Didn't get an exception from Field.class.getDeclaredConstructor().setAccessible");
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700722 } catch (SecurityException e) {
Mathieu Chartier3ed4c542014-08-08 15:10:11 -0700723 } catch (NoSuchMethodException e) {
724 } catch (Exception e) {
Narayan Kamath3778c872015-11-17 13:46:30 +0000725 System.out.println(e);
Mathieu Chartier3ed4c542014-08-08 15:10:11 -0700726 }
727 try {
728 Class.class.getDeclaredConstructor().setAccessible(true);
Narayan Kamath3778c872015-11-17 13:46:30 +0000729 System.out.println("Didn't get an exception from Class.class.getDeclaredConstructor().setAccessible");
Mathieu Chartier3ed4c542014-08-08 15:10:11 -0700730 } catch (SecurityException e) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700731 } catch (NoSuchMethodException e) {
Mathieu Chartier3ed4c542014-08-08 15:10:11 -0700732 } catch (Exception e) {
Narayan Kamath3778c872015-11-17 13:46:30 +0000733 System.out.println(e);
Mathieu Chartier3ed4c542014-08-08 15:10:11 -0700734 }
735 }
736
Mathieu Chartierca239af2015-03-29 18:27:50 -0700737 static void checkPrivateFieldAccess() {
738 (new OtherClass()).test();
739 }
740
Elliott Hughes923e8b82012-03-23 11:44:07 -0700741 public static void main(String[] args) throws Exception {
jeffhao5d1ac922011-09-29 17:41:15 -0700742 Main test = new Main();
743 test.run();
744
Mathieu Chartier3ed4c542014-08-08 15:10:11 -0700745 checkGetDeclaredConstructor();
Elliott Hughes741b5b72012-01-31 19:18:51 -0800746 checkAccess();
Narayan Kamath3778c872015-11-17 13:46:30 +0000747 checkSwap();
Elliott Hughes923e8b82012-03-23 11:44:07 -0700748 checkClinitForFields();
749 checkClinitForMethods();
Elliott Hughes741b5b72012-01-31 19:18:51 -0800750 checkGeneric();
Brian Carlstromea46f952013-07-30 01:26:50 -0700751 checkUnique();
Piotr Jastrzebski68b539e2014-08-06 12:02:48 +0100752 checkParametrizedTypeEqualsAndHashCode();
753 checkGenericArrayTypeEqualsAndHashCode();
Mathieu Chartierca239af2015-03-29 18:27:50 -0700754 checkPrivateFieldAccess();
jeffhao5d1ac922011-09-29 17:41:15 -0700755 }
756}
757
758
759class SuperTarget {
760 public SuperTarget() {
761 System.out.println("SuperTarget constructor ()V");
762 superInt = 1010101;
763 superClassInt = 1010102;
764 }
765
766 public int myMethod(float floatArg) {
767 System.out.println("myMethod (F)I " + floatArg);
768 return 6;
769 }
770
771 public int superInt;
772 public static int superClassInt;
773}
774
775class Target extends SuperTarget {
776 public Target() {
777 System.out.println("Target constructor ()V");
778 }
779
780 public Target(int ii, float ff) {
781 System.out.println("Target constructor (IF)V : ii="
782 + ii + " ff=" + ff);
783 anInt = ii;
784 }
785
786 public int myMethod(int intarg) throws NullPointerException, IOException {
787 System.out.println("myMethod (I)I");
788 System.out.println(" arg=" + intarg + " anInt=" + anInt);
789 return 5;
790 }
791
792 public int myMethod(String[] strarg, float f, char c) {
793 System.out.println("myMethod: " + strarg[0] + " " + f + " " + c + " !");
794 return 7;
795 }
796
797 public static void myNoargMethod() {
798 System.out.println("myNoargMethod ()V");
799 }
800
801 public void throwingMethod() {
802 System.out.println("throwingMethod");
803 throw new NullPointerException("gratuitous throw!");
804 }
805
806 public void misc() {
807 System.out.println("misc");
808 }
809
810 public int anInt;
811 public String string1 = "hey";
812 public String string2 = "yo";
813 public String string3 = "there";
814 private String string4 = "naughty";
815 public static final String constantString = "a constant string";
816 private int aPrivateInt;
817
818 public final int cantTouchThis = 77;
819
820 public long pubLong = 0x1122334455667788L;
821
822 public static double staticDouble = 3.3;
823}
824
Elliott Hughes923e8b82012-03-23 11:44:07 -0700825class FieldNoisyInit {
Mathieu Chartierca239af2015-03-29 18:27:50 -0700826 static {
827 System.out.println("FieldNoisyInit is initializing");
828 //Throwable th = new Throwable();
829 //th.printStackTrace();
830 }
jeffhao5d1ac922011-09-29 17:41:15 -0700831}
832
Elliott Hughes923e8b82012-03-23 11:44:07 -0700833class FieldNoisyInitUser {
Mathieu Chartierca239af2015-03-29 18:27:50 -0700834 static {
835 System.out.println("FieldNoisyInitUser is initializing");
836 }
837 public static int staticField;
838 public static FieldNoisyInit noisy;
Elliott Hughes923e8b82012-03-23 11:44:07 -0700839}
840
841class MethodNoisyInit {
Mathieu Chartierca239af2015-03-29 18:27:50 -0700842 static {
843 System.out.println("MethodNoisyInit is initializing");
844 //Throwable th = new Throwable();
845 //th.printStackTrace();
846 }
Elliott Hughes923e8b82012-03-23 11:44:07 -0700847}
848
849class MethodNoisyInitUser {
Mathieu Chartierca239af2015-03-29 18:27:50 -0700850 static {
851 System.out.println("MethodNoisyInitUser is initializing");
852 }
853 public static void staticMethod() {}
854 public void createMethodNoisyInit(MethodNoisyInit ni) {}
jeffhao5d1ac922011-09-29 17:41:15 -0700855}
Jeff Hao63f5b9e2014-04-23 14:51:46 -0700856
857class Thrower {
Mathieu Chartierca239af2015-03-29 18:27:50 -0700858 public Thrower() throws UnsupportedOperationException {
859 throw new UnsupportedOperationException();
860 }
Jeff Hao63f5b9e2014-04-23 14:51:46 -0700861}
Piotr Jastrzebski68b539e2014-08-06 12:02:48 +0100862
863class ParametrizedTypeTest {
864 public void aMethod(Set<String> names) {}
865 public void aMethodIdentical(Set<String> names) {}
866}
867
868class GenericArrayTypeTest<T> {
869 public void aMethod(T[] names) {}
870 public void aMethodIdentical(T[] names) {}
871}
Mathieu Chartierca239af2015-03-29 18:27:50 -0700872
873class OtherClass {
874 private static final long LONG = 1234;
875 public void test() {
876 try {
877 Field field = getClass().getDeclaredField("LONG");
878 if (1234 != field.getLong(null)) {
879 System.out.println("ERROR: values don't match");
880 }
881 } catch (Exception e) {
882 System.out.println(e);
883 }
884 }
Mathieu Chartier3beb2452015-05-13 13:13:24 -0700885}