Home | History | Annotate | Download | only in src
      1 /*
      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  */
     16 
     17 import java.lang.reflect.*;
     18 import java.io.IOException;
     19 import java.util.Collections;
     20 import java.util.ArrayList;
     21 import java.util.Arrays;
     22 import java.util.List;
     23 import java.util.Map;
     24 import java.util.Set;
     25 
     26 /**
     27  * Reflection test.
     28  */
     29 public class Main {
     30     private static boolean FULL_ACCESS_CHECKS = false;  // b/5861201
     31     public Main() {}
     32     public Main(ArrayList<Integer> stuff) {}
     33 
     34     void printMethodInfo(Method meth) {
     35         Class<?>[] params, exceptions;
     36         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 
     65         Class<?> target = Target.class;
     66         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 
     81     public static void checkAccess() {
     82         try {
     83             Class<?> target = otherpackage.Other.class;
     84             Object instance = new otherpackage.Other();
     85             Method meth;
     86 
     87             meth = target.getMethod("publicMethod");
     88             meth.invoke(instance);
     89 
     90             try {
     91                 meth = target.getMethod("packageMethod");
     92                 System.out.println("succeeded on package-scope method");
     93             } catch (NoSuchMethodException nsme) {
     94                 // good
     95             }
     96 
     97 
     98             instance = otherpackage.Other.getInnerClassInstance();
     99             target = instance.getClass();
    100             meth = target.getMethod("innerMethod");
    101             try {
    102                 if (!FULL_ACCESS_CHECKS) { throw new IllegalAccessException(); }
    103                 meth.invoke(instance);
    104                 System.out.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.out.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(System.out);
    120         }
    121     }
    122 
    123     public void run() {
    124         Class<Target> target = Target.class;
    125         Method meth = null;
    126         Field field = null;
    127         boolean excep;
    128 
    129         try {
    130             meth = target.getMethod("myMethod", int.class);
    131 
    132             if (meth.getDeclaringClass() != target)
    133                 throw new RuntimeException();
    134             printMethodInfo(meth);
    135 
    136             meth = target.getMethod("myMethod", float.class);
    137             printMethodInfo(meth);
    138 
    139             meth = target.getMethod("myNoargMethod");
    140             printMethodInfo(meth);
    141 
    142             meth = target.getMethod("myMethod", String[].class, float.class, char.class);
    143             printMethodInfo(meth);
    144 
    145             Target instance = new Target();
    146             Object[] argList = new Object[] {
    147                 new String[] { "hi there" },
    148                 new Float(3.1415926f),
    149                 new Character('\u2714')
    150             };
    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");
    159             meth = target.getMethod("myNoargMethod");
    160             meth.invoke(instance, (Object[]) null);
    161 
    162             /* try invoking a method that throws an exception */
    163             meth = target.getMethod("throwingMethod");
    164             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(System.out);
    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             /*
    235              * 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             /*
    249              * 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);
    353                 System.out.println("ERROR: set-final did not throw exception");
    354             } catch (IllegalAccessException iae) {
    355                 System.out.println("  as expected: set-final throws exception");
    356             }
    357             intVal = field.getInt(instance);
    358             System.out.println("  cantTouchThis is still " + intVal);
    359 
    360             System.out.println("  " + field + " accessible=" + field.isAccessible());
    361             field.setAccessible(true);
    362             System.out.println("  " + field + " accessible=" + field.isAccessible());
    363             field.setInt(instance, 87);     // exercise int version
    364             intVal = field.getInt(instance);
    365             System.out.println("  cantTouchThis is now " + intVal);
    366             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 
    374             cons = target.getConstructor(int.class, float.class);
    375             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 
    380             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 
    401         } catch (Exception ex) {
    402             System.out.println("----- unexpected exception -----");
    403             ex.printStackTrace(System.out);
    404         }
    405 
    406         System.out.println("ReflectTest done!");
    407     }
    408 
    409     public static void checkSwap() {
    410         Method m;
    411 
    412         final Object[] objects = new Object[2];
    413         try {
    414             m = Collections.class.getDeclaredMethod("swap",
    415                             Object[].class, int.class, int.class);
    416         } catch (NoSuchMethodException nsme) {
    417             nsme.printStackTrace(System.out);
    418             return;
    419         }
    420         System.out.println(m + " accessible=" + m.isAccessible());
    421         m.setAccessible(true);
    422         System.out.println(m + " accessible=" + m.isAccessible());
    423         try {
    424             m.invoke(null, objects, 0, 1);
    425         } catch (IllegalAccessException iae) {
    426             iae.printStackTrace(System.out);
    427             return;
    428         } catch (InvocationTargetException ite) {
    429             ite.printStackTrace(System.out);
    430             return;
    431         }
    432 
    433         try {
    434             String s = "Should be ignored";
    435             m.invoke(s, objects, 0, 1);
    436         } catch (IllegalAccessException iae) {
    437             iae.printStackTrace(System.out);
    438             return;
    439         } catch (InvocationTargetException ite) {
    440             ite.printStackTrace(System.out);
    441             return;
    442         }
    443 
    444         try {
    445             System.out.println("checkType invoking null");
    446             // Trigger an NPE at the target.
    447             m.invoke(null, null, 0, 1);
    448             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(System.out);
    453             return;
    454         }
    455     }
    456 
    457     public static void checkClinitForFields() throws Exception {
    458       // Loading a class constant shouldn't run <clinit>.
    459       System.out.println("calling const-class FieldNoisyInitUser.class");
    460       Class<?> niuClass = FieldNoisyInitUser.class;
    461       System.out.println("called const-class FieldNoisyInitUser.class");
    462 
    463       // Getting the declared fields doesn't run <clinit>.
    464       Field[] fields = niuClass.getDeclaredFields();
    465       System.out.println("got fields");
    466 
    467       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");
    482       Class<?> niuClass = MethodNoisyInitUser.class;
    483       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 
    489       Method method = niuClass.getMethod("staticMethod");
    490       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("");
    499     }
    500 
    501 
    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 {
    519             method = Main.class.getMethod("fancyMethod", ArrayList.class);
    520         } 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 
    528         Constructor<?> ctor;
    529         try {
    530             ctor = Main.class.getConstructor( ArrayList.class);
    531         } 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 
    561     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 {
    581             method1 = Main.class.getMethod("fancyMethod", ArrayList.class);
    582             method2 = Main.class.getMethod("fancyMethod", ArrayList.class);
    583         } 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     }
    597 
    598     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 
    710     private static void checkGetDeclaredConstructor() {
    711         try {
    712             Method.class.getDeclaredConstructor().setAccessible(true);
    713             System.out.println("Didn't get an exception from Method.class.getDeclaredConstructor().setAccessible");
    714         } catch (SecurityException e) {
    715         } catch (NoSuchMethodException e) {
    716         } catch (Exception e) {
    717             System.out.println(e);
    718         }
    719         try {
    720             Field.class.getDeclaredConstructor().setAccessible(true);
    721             System.out.println("Didn't get an exception from Field.class.getDeclaredConstructor().setAccessible");
    722         } catch (SecurityException e) {
    723         } catch (NoSuchMethodException e) {
    724         } catch (Exception e) {
    725             System.out.println(e);
    726         }
    727         try {
    728             Class.class.getDeclaredConstructor().setAccessible(true);
    729             System.out.println("Didn't get an exception from Class.class.getDeclaredConstructor().setAccessible");
    730         } catch (SecurityException e) {
    731         } catch (NoSuchMethodException e) {
    732         } catch (Exception e) {
    733             System.out.println(e);
    734         }
    735     }
    736 
    737     static void checkPrivateFieldAccess() {
    738         (new OtherClass()).test();
    739     }
    740 
    741     public static void main(String[] args) throws Exception {
    742         Main test = new Main();
    743         test.run();
    744 
    745         checkGetDeclaredConstructor();
    746         checkAccess();
    747         checkSwap();
    748         checkClinitForFields();
    749         checkClinitForMethods();
    750         checkGeneric();
    751         checkUnique();
    752         checkParametrizedTypeEqualsAndHashCode();
    753         checkGenericArrayTypeEqualsAndHashCode();
    754         checkPrivateFieldAccess();
    755     }
    756 }
    757 
    758 
    759 class 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 
    775 class 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 
    825 class FieldNoisyInit {
    826     static {
    827         System.out.println("FieldNoisyInit is initializing");
    828         //Throwable th = new Throwable();
    829         //th.printStackTrace(System.out);
    830     }
    831 }
    832 
    833 class FieldNoisyInitUser {
    834     static {
    835         System.out.println("FieldNoisyInitUser is initializing");
    836     }
    837     public static int staticField;
    838     public static FieldNoisyInit noisy;
    839 }
    840 
    841 class MethodNoisyInit {
    842     static {
    843         System.out.println("MethodNoisyInit is initializing");
    844         //Throwable th = new Throwable();
    845         //th.printStackTrace(System.out);
    846     }
    847 }
    848 
    849 class MethodNoisyInitUser {
    850     static {
    851         System.out.println("MethodNoisyInitUser is initializing");
    852     }
    853     public static void staticMethod() {}
    854     public void createMethodNoisyInit(MethodNoisyInit ni) {}
    855 }
    856 
    857 class Thrower {
    858     public Thrower() throws UnsupportedOperationException {
    859         throw new UnsupportedOperationException();
    860     }
    861 }
    862 
    863 class ParametrizedTypeTest {
    864     public void aMethod(Set<String> names) {}
    865     public void aMethodIdentical(Set<String> names) {}
    866 }
    867 
    868 class GenericArrayTypeTest<T> {
    869     public void aMethod(T[] names) {}
    870     public void aMethodIdentical(T[] names) {}
    871 }
    872 
    873 class 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     }
    885 }
    886