content: /*
   * Copyright (C) 2006 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  import java.lang.reflect.*;
  import java.io.IOException;
  import java.util.Collections;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  /**
   * Reflection test.
   */
  public class Main {
      private static boolean FULL_ACCESS_CHECKS = false;  // b/5861201
      public Main() {}
      public Main(ArrayList<Integer> stuff) {}
  
      void printMethodInfo(Method meth) {
          Class[] params, exceptions;
          int i;
  
          System.out.println("Method name is " + meth.getName());
          System.out.println(" Declaring class is "
              + meth.getDeclaringClass().getName());
          params = meth.getParameterTypes();
          for (i = 0; i < params.length; i++)
              System.out.println(" Arg " + i + ": " + params[i].getName());
          exceptions = meth.getExceptionTypes();
          for (i = 0; i < exceptions.length; i++)
              System.out.println(" Exc " + i + ": " + exceptions[i].getName());
          System.out.println(" Return type is " + meth.getReturnType().getName());
          System.out.println(" Access flags are 0x"
              + Integer.toHexString(meth.getModifiers()));
          //System.out.println(" GenericStr is " + meth.toGenericString());
      }
  
      void printFieldInfo(Field field) {
          System.out.println("Field name is " + field.getName());
          System.out.println(" Declaring class is "
              + field.getDeclaringClass().getName());
          System.out.println(" Field type is " + field.getType().getName());
          System.out.println(" Access flags are 0x"
              + Integer.toHexString(field.getModifiers()));
      }
  
      private void showStrings(Target instance)
          throws NoSuchFieldException, IllegalAccessException {
  
          Class target = Target.class;
          String one, two, three, four;
          Field field = null;
  
          field = target.getField("string1");
          one = (String) field.get(instance);
  
          field = target.getField("string2");
          two = (String) field.get(instance);
  
          field = target.getField("string3");
          three = (String) field.get(instance);
  
          System.out.println("  ::: " + one + ":" + two + ":" + three);
      }
  
      public static void checkAccess() {
          try {
              Class target = otherpackage.Other.class;
              Object instance = new otherpackage.Other();
              Method meth;
  
              meth = target.getMethod("publicMethod", (Class[]) null);
              meth.invoke(instance);
  
              try {
                  meth = target.getMethod("packageMethod", (Class[]) null);
                  System.err.println("succeeded on package-scope method");
              } catch (NoSuchMethodException nsme) {
                  // good
              }
  
  
              instance = otherpackage.Other.getInnerClassInstance();
              target = instance.getClass();
              meth = target.getMethod("innerMethod", (Class[]) null);
              try {
                  if (!FULL_ACCESS_CHECKS) { throw new IllegalAccessException(); }
                  meth.invoke(instance);
                  System.err.println("inner-method invoke unexpectedly worked");
              } catch (IllegalAccessException iae) {
                  // good
              }
  
              Field field = target.getField("innerField");
              try {
                  int x = field.getInt(instance);
                  if (!FULL_ACCESS_CHECKS) { throw new IllegalAccessException(); }
                  System.err.println("field get unexpectedly worked: " + x);
              } catch (IllegalAccessException iae) {
                  // good
              }
          } catch (Exception ex) {
              System.out.println("----- unexpected exception -----");
              ex.printStackTrace();
          }
      }
  
      public void run() {
          Class target = Target.class;
          Method meth = null;
          Field field = null;
          boolean excep;
  
          try {
              meth = target.getMethod("myMethod", new Class[] { int.class });
  
              if (meth.getDeclaringClass() != target)
                  throw new RuntimeException();
              printMethodInfo(meth);
  
              meth = target.getMethod("myMethod", new Class[] { float.class });
              printMethodInfo(meth);
  
              meth = target.getMethod("myNoargMethod", (Class[]) null);
              printMethodInfo(meth);
  
              meth = target.getMethod("myMethod",
                  new Class[] { String[].class, float.class, char.class });
              printMethodInfo(meth);
  
              Target instance = new Target();
              Object[] argList = new Object[] {
                  new String[] { "hi there" },
                  new Float(3.1415926f),
                  new Character('\u2714')
              };
              System.out.println("Before, float is "
                  + ((Float)argList[1]).floatValue());
  
              Integer boxval;
              boxval = (Integer) meth.invoke(instance, argList);
              System.out.println("Result of invoke: " + boxval.intValue());
  
              System.out.println("Calling no-arg void-return method");
              meth = target.getMethod("myNoargMethod", (Class[]) null);
              meth.invoke(instance, (Object[]) null);
  
              /* try invoking a method that throws an exception */
              meth = target.getMethod("throwingMethod", (Class[]) null);
              try {
                  meth.invoke(instance, (Object[]) null);
                  System.out.println("GLITCH: didn't throw");
              } catch (InvocationTargetException ite) {
                  System.out.println("Invoke got expected exception:");
                  System.out.println(ite.getClass().getName());
                  System.out.println(ite.getCause());
              }
              catch (Exception ex) {
                  System.out.println("GLITCH: invoke got wrong exception:");
                  ex.printStackTrace();
              }
              System.out.println("");
  
  
              field = target.getField("string1");
              if (field.getDeclaringClass() != target)
                  throw new RuntimeException();
              printFieldInfo(field);
              String strVal = (String) field.get(instance);
              System.out.println("  string1 value is '" + strVal + "'");
  
              showStrings(instance);
  
              field.set(instance, new String("a new string"));
              strVal = (String) field.get(instance);
              System.out.println("  string1 value is now '" + strVal + "'");
  
              showStrings(instance);
  
              try {
                  field.set(instance, new Object());
                  System.out.println("WARNING: able to store Object into String");
              }
              catch (IllegalArgumentException iae) {
                  System.out.println("  got expected illegal obj store exc");
              }
  
  
              try {
                  String four;
                  field = target.getField("string4");
                  four = (String) field.get(instance);
                  System.out.println("WARNING: able to access string4: "
                      + four);
              }
              catch (IllegalAccessException iae) {
                  System.out.println("  got expected access exc");
              }
              catch (NoSuchFieldException nsfe) {
                  System.out.println("  got the other expected access exc");
              }
              try {
                  String three;
                  field = target.getField("string3");
                  three = (String) field.get(this);
                  System.out.println("WARNING: able to get string3 in wrong obj: "
                      + three);
              }
              catch (IllegalArgumentException iae) {
                  System.out.println("  got expected arg exc");
              }
  
              /*
               * Try setting a field to null.
               */
              String four;
              field = target.getDeclaredField("string3");
              field.set(instance, null);
  
              /*
               * Try getDeclaredField on a non-existant field.
               */
              try {
                  field = target.getDeclaredField("nonExistant");
                  System.out.println("ERROR: Expected NoSuchFieldException");
              } catch (NoSuchFieldException nsfe) {
                  String msg = nsfe.getMessage();
                  if (!msg.contains("Target;")) {
                      System.out.println("  NoSuchFieldException '" + msg +
                          "' didn't contain class");
                  }
              }
  
              /*
               * Do some stuff with long.
               */
              long longVal;
              field = target.getField("pubLong");
              longVal = field.getLong(instance);
              System.out.println("pubLong initial value is " +
                  Long.toHexString(longVal));
              field.setLong(instance, 0x9988776655443322L);
              longVal = field.getLong(instance);
              System.out.println("pubLong new value is " +
                  Long.toHexString(longVal));
  
  
              field = target.getField("superInt");
              if (field.getDeclaringClass() == target)
                  throw new RuntimeException();
              printFieldInfo(field);
              int intVal = field.getInt(instance);
              System.out.println("  superInt value is " + intVal);
              Integer boxedIntVal = (Integer) field.get(instance);
              System.out.println("  superInt boxed is " + boxedIntVal);
  
              field.set(instance, new Integer(20202));
              intVal = field.getInt(instance);
              System.out.println("  superInt value is now " + intVal);
              field.setShort(instance, (short)30303);
              intVal = field.getInt(instance);
              System.out.println("  superInt value (from short) is now " +intVal);
              field.setInt(instance, 40404);
              intVal = field.getInt(instance);
              System.out.println("  superInt value is now " + intVal);
              try {
                  field.set(instance, new Long(123));
                  System.out.println("FAIL: expected exception not thrown");
              }
              catch (IllegalArgumentException iae) {
                  System.out.println("  got expected long->int failure");
              }
              try {
                  field.setLong(instance, 123);
                  System.out.println("FAIL: expected exception not thrown");
              }
              catch (IllegalArgumentException iae) {
                  System.out.println("  got expected long->int failure");
              }
              try {
                  field.set(instance, new String("abc"));
                  System.out.println("FAIL: expected exception not thrown");
              }
              catch (IllegalArgumentException iae) {
                  System.out.println("  got expected string->int failure");
              }
  
              try {
                  field.getShort(instance);
                  System.out.println("FAIL: expected exception not thrown");
              }
              catch (IllegalArgumentException iae) {
                  System.out.println("  got expected int->short failure");
              }
  
              field = target.getField("superClassInt");
              printFieldInfo(field);
              int superClassIntVal = field.getInt(instance);
              System.out.println("  superClassInt value is " + superClassIntVal);
  
              field = target.getField("staticDouble");
              printFieldInfo(field);
              double staticDoubleVal = field.getDouble(null);
              System.out.println("  staticDoubleVal value is " + staticDoubleVal);
  
              try {
                  field.getLong(instance);
                  System.out.println("FAIL: expected exception not thrown");
              }
              catch (IllegalArgumentException iae) {
                  System.out.println("  got expected double->long failure");
              }
  
              excep = false;
              try {
                  field = target.getField("aPrivateInt");
                  printFieldInfo(field);
              }
              catch (NoSuchFieldException nsfe) {
                  System.out.println("as expected: aPrivateInt not found");
                  excep = true;
              }
              if (!excep)
                  System.out.println("BUG: got aPrivateInt");
  
  
              field = target.getField("constantString");
              printFieldInfo(field);
              String val = (String) field.get(instance);
              System.out.println("  Constant test value is " + val);
  
  
              field = target.getField("cantTouchThis");
              printFieldInfo(field);
              intVal = field.getInt(instance);
              System.out.println("  cantTouchThis is " + intVal);
              try {
                  field.setInt(instance, 99);
                  System.out.println("ERROR: set-final did not throw exception");
              } catch (IllegalAccessException iae) {
                  System.out.println("  as expected: set-final throws exception");
              }
              intVal = field.getInt(instance);
              System.out.println("  cantTouchThis is still " + intVal);
  
              System.out.println("  " + field + " accessible=" + field.isAccessible());
              field.setAccessible(true);
              System.out.println("  " + field + " accessible=" + field.isAccessible());
              field.setInt(instance, 87);     // exercise int version
              intVal = field.getInt(instance);
              System.out.println("  cantTouchThis is now " + intVal);
              field.set(instance, 88);        // exercise Object version
              intVal = field.getInt(instance);
              System.out.println("  cantTouchThis is now " + intVal);
  
              Constructor<Target> cons;
              Target targ;
              Object[] args;
  
              cons = target.getConstructor(new Class[] { int.class,float.class });
              args = new Object[] { new Integer(7), new Float(3.3333) };
              System.out.println("cons modifiers=" + cons.getModifiers());
              targ = cons.newInstance(args);
              targ.myMethod(17);
  
              try {
                  Thrower thrower = Thrower.class.newInstance();
                  System.out.println("ERROR: Class.newInstance did not throw exception");
              } catch (UnsupportedOperationException uoe) {
                  System.out.println("got expected exception for Class.newInstance");
              } catch (Exception e) {
                  System.out.println("ERROR: Class.newInstance got unexpected exception: " +
                                     e.getClass().getName());
              }
  
              try {
                  Constructor<Thrower> constructor = Thrower.class.getDeclaredConstructor();
                  Thrower thrower = constructor.newInstance();
                  System.out.println("ERROR: Constructor.newInstance did not throw exception");
              } catch (InvocationTargetException ite) {
                  System.out.println("got expected exception for Constructor.newInstance");
              } catch (Exception e) {
                  System.out.println("ERROR: Constructor.newInstance got unexpected exception: " +
                                     e.getClass().getName());
              }
  
          } catch (Exception ex) {
              System.out.println("----- unexpected exception -----");
              ex.printStackTrace();
          }
  
          System.out.println("ReflectTest done!");
      }
  
      public static void checkSwap() {
          Method m;
  
          final Object[] objects = new Object[2];
          try {
              m = Collections.class.getDeclaredMethod("swap",
                              Object[].class, int.class, int.class);
          } catch (NoSuchMethodException nsme) {
              nsme.printStackTrace();
              return;
          }
          System.out.println(m + " accessible=" + m.isAccessible());
          m.setAccessible(true);
          System.out.println(m + " accessible=" + m.isAccessible());
          try {
              m.invoke(null, objects, 0, 1);
          } catch (IllegalAccessException iae) {
              iae.printStackTrace();
              return;
          } catch (InvocationTargetException ite) {
              ite.printStackTrace();
              return;
          }
  
          try {
              String s = "Should be ignored";
              m.invoke(s, objects, 0, 1);
          } catch (IllegalAccessException iae) {
              iae.printStackTrace();
              return;
          } catch (InvocationTargetException ite) {
              ite.printStackTrace();
              return;
          }
  
          try {
              System.out.println("checkType invoking null");
              // Trigger an NPE at the target.
              m.invoke(null, null, 0, 1);
              System.out.println("ERROR: should throw InvocationTargetException");
          } catch (InvocationTargetException ite) {
              System.out.println("checkType got expected exception");
          } catch (IllegalAccessException iae) {
              iae.printStackTrace();
              return;
          }
      }
  
      public static void checkClinitForFields() throws Exception {
        // Loading a class constant shouldn't run <clinit>.
        System.out.println("calling const-class FieldNoisyInitUser.class");
        Class niuClass = FieldNoisyInitUser.class;
        System.out.println("called const-class FieldNoisyInitUser.class");
  
        // Getting the declared fields doesn't run <clinit>.
        Field[] fields = niuClass.getDeclaredFields();
        System.out.println("got fields");
  
        Field field = niuClass.getField("staticField");
        System.out.println("got field");
        field.get(null);
        System.out.println("read field value");
  
        // FieldNoisyInitUser should now be initialized, but FieldNoisyInit shouldn't be initialized yet.
        FieldNoisyInitUser niu = new FieldNoisyInitUser();
        FieldNoisyInit ni = new FieldNoisyInit();
  
        System.out.println("");
      }
  
      public static void checkClinitForMethods() throws Exception {
        // Loading a class constant shouldn't run <clinit>.
        System.out.println("calling const-class MethodNoisyInitUser.class");
        Class niuClass = MethodNoisyInitUser.class;
        System.out.println("called const-class MethodNoisyInitUser.class");
  
        // Getting the declared methods doesn't run <clinit>.
        Method[] methods = niuClass.getDeclaredMethods();
        System.out.println("got methods");
  
        Method method = niuClass.getMethod("staticMethod", (Class[]) null);
        System.out.println("got method");
        method.invoke(null);
        System.out.println("invoked method");
  
        // MethodNoisyInitUser should now be initialized, but MethodNoisyInit shouldn't be initialized yet.
        MethodNoisyInitUser niu = new MethodNoisyInitUser();
        MethodNoisyInit ni = new MethodNoisyInit();
  
        System.out.println("");
      }
  
  
      /*
       * Test some generic type stuff.
       */
      public List<String> dummy;
      public Map<Integer,String> fancyMethod(ArrayList<String> blah) { return null; }
      public static void checkGeneric() {
          Field field;
          try {
              field = Main.class.getField("dummy");
          } catch (NoSuchFieldException nsfe) {
              throw new RuntimeException(nsfe);
          }
          Type listType = field.getGenericType();
          System.out.println("generic field: " + listType);
  
          Method method;
          try {
              method = Main.class.getMethod("fancyMethod",
                  new Class[] { ArrayList.class });
          } catch (NoSuchMethodException nsme) {
              throw new RuntimeException(nsme);
          }
          Type[] parmTypes = method.getGenericParameterTypes();
          Type ret = method.getGenericReturnType();
          System.out.println("generic method " + method.getName() + " params='"
              + stringifyTypeArray(parmTypes) + "' ret='" + ret + "'");
  
          Constructor ctor;
          try {
              ctor = Main.class.getConstructor(new Class[] { ArrayList.class });
          } catch (NoSuchMethodException nsme) {
              throw new RuntimeException(nsme);
          }
          parmTypes = ctor.getGenericParameterTypes();
          System.out.println("generic ctor " + ctor.getName() + " params='"
              + stringifyTypeArray(parmTypes) + "'");
      }
  
      /*
       * Convert an array of Type into a string.  Start with an array count.
       */
      private static String stringifyTypeArray(Type[] types) {
          StringBuilder stb = new StringBuilder();
          boolean first = true;
  
          stb.append("[" + types.length + "]");
  
          for (Type t: types) {
              if (first) {
                  stb.append(" ");
                  first = false;
              } else {
                  stb.append(", ");
              }
              stb.append(t.toString());
          }
  
          return stb.toString();
      }
  
      public static void checkUnique() {
          Field field1, field2;
          try {
              field1 = Main.class.getField("dummy");
              field2 = Main.class.getField("dummy");
          } catch (NoSuchFieldException nsfe) {
              throw new RuntimeException(nsfe);
          }
          if (field1 == field2) {
              System.out.println("ERROR: fields shouldn't have reference equality");
          } else {
              System.out.println("fields are unique");
          }
          if (field1.hashCode() == field2.hashCode() && field1.equals(field2)) {
              System.out.println("fields are .equals");
          } else {
              System.out.println("ERROR: fields fail equality");
          }
          Method method1, method2;
          try {
              method1 = Main.class.getMethod("fancyMethod", new Class[] { ArrayList.class });
              method2 = Main.class.getMethod("fancyMethod", new Class[] { ArrayList.class });
          } catch (NoSuchMethodException nsme) {
              throw new RuntimeException(nsme);
          }
          if (method1 == method2) {
              System.out.println("ERROR: methods shouldn't have reference equality");
          } else {
              System.out.println("methods are unique");
          }
          if (method1.hashCode() == method2.hashCode() && method1.equals(method2)) {
              System.out.println("methods are .equals");
          } else {
              System.out.println("ERROR: methods fail equality");
          }
      }
  
      public static void checkParametrizedTypeEqualsAndHashCode() {
          Method method1;
          Method method2;
          Method method3;
          try {
              method1 = ParametrizedTypeTest.class.getDeclaredMethod("aMethod", Set.class);
              method2 = ParametrizedTypeTest.class.getDeclaredMethod("aMethod", Set.class);
              method3 = ParametrizedTypeTest.class.getDeclaredMethod("aMethodIdentical", Set.class);
          } catch (NoSuchMethodException nsme) {
              throw new RuntimeException(nsme);
          }
  
          List<Type> types1 = Arrays.asList(method1.getGenericParameterTypes());
          List<Type> types2 = Arrays.asList(method2.getGenericParameterTypes());
          List<Type> types3 = Arrays.asList(method3.getGenericParameterTypes());
  
          Type type1 = types1.get(0);
          Type type2 = types2.get(0);
          Type type3 = types3.get(0);
  
          if (type1 instanceof ParameterizedType) {
              System.out.println("type1 is a ParameterizedType");
          }
          if (type2 instanceof ParameterizedType) {
              System.out.println("type2 is a ParameterizedType");
          }
          if (type3 instanceof ParameterizedType) {
              System.out.println("type3 is a ParameterizedType");
          }
  
          if (type1.equals(type2)) {
              System.out.println("type1("+type1+") equals type2("+type2+")");
          } else {
              System.out.println("type1("+type1+") does not equal type2("+type2+")");
          }
  
          if (type1.equals(type3)) {
              System.out.println("type1("+type1+") equals type3("+type3+")");
          } else {
              System.out.println("type1("+type1+") does not equal type3("+type3+")");
          }
          if (type1.hashCode() == type2.hashCode()) {
              System.out.println("type1("+type1+") hashCode equals type2("+type2+") hashCode");
          } else {
              System.out.println(
                     "type1("+type1+") hashCode does not equal type2("+type2+") hashCode");
          }
  
          if (type1.hashCode() == type3.hashCode()) {
              System.out.println("type1("+type1+") hashCode equals type3("+type3+") hashCode");
          } else {
              System.out.println(
                      "type1("+type1+") hashCode does not equal type3("+type3+") hashCode");
          }
      }
  
      public static void checkGenericArrayTypeEqualsAndHashCode() {
          Method method1;
          Method method2;
          Method method3;
          try {
              method1 = GenericArrayTypeTest.class.getDeclaredMethod("aMethod", Object[].class);
              method2 = GenericArrayTypeTest.class.getDeclaredMethod("aMethod", Object[].class);
              method3 = GenericArrayTypeTest.class.getDeclaredMethod("aMethodIdentical", Object[].class);
          } catch (NoSuchMethodException nsme) {
              throw new RuntimeException(nsme);
          }
  
          List<Type> types1 = Arrays.asList(method1.getGenericParameterTypes());
          List<Type> types2 = Arrays.asList(method2.getGenericParameterTypes());
          List<Type> types3 = Arrays.asList(method3.getGenericParameterTypes());
  
          Type type1 = types1.get(0);
          Type type2 = types2.get(0);
          Type type3 = types3.get(0);
  
          if (type1 instanceof GenericArrayType) {
              System.out.println("type1 is a GenericArrayType");
          }
          if (type2 instanceof GenericArrayType) {
              System.out.println("type2 is a GenericArrayType");
          }
          if (type3 instanceof GenericArrayType) {
              System.out.println("type3 is a GenericArrayType");
          }
  
          if (type1.equals(type2)) {
              System.out.println("type1("+type1+") equals type2("+type2+")");
          } else {
              System.out.println("type1("+type1+") does not equal type2("+type2+")");
          }
  
          if (type1.equals(type3)) {
              System.out.println("type1("+type1+") equals type3("+type3+")");
          } else {
              System.out.println("type1("+type1+") does not equal type3("+type3+")");
          }
          if (type1.hashCode() == type2.hashCode()) {
              System.out.println("type1("+type1+") hashCode equals type2("+type2+") hashCode");
          } else {
              System.out.println(
                     "type1("+type1+") hashCode does not equal type2("+type2+") hashCode");
          }
  
          if (type1.hashCode() == type3.hashCode()) {
              System.out.println("type1("+type1+") hashCode equals type3("+type3+") hashCode");
          } else {
              System.out.println(
                      "type1("+type1+") hashCode does not equal type3("+type3+") hashCode");
          }
      }
  
      private static void checkGetDeclaredConstructor() {
          try {
              Method.class.getDeclaredConstructor().setAccessible(true);
              System.out.println("Didn't get an exception from Method.class.getDeclaredConstructor().setAccessible");
          } catch (SecurityException e) {
          } catch (NoSuchMethodException e) {
          } catch (Exception e) {
              System.out.println(e);
          }
          try {
              Field.class.getDeclaredConstructor().setAccessible(true);
              System.out.println("Didn't get an exception from Field.class.getDeclaredConstructor().setAccessible");
          } catch (SecurityException e) {
          } catch (NoSuchMethodException e) {
          } catch (Exception e) {
              System.out.println(e);
          }
          try {
              Class.class.getDeclaredConstructor().setAccessible(true);
              System.out.println("Didn't get an exception from Class.class.getDeclaredConstructor().setAccessible");
          } catch (SecurityException e) {
          } catch (NoSuchMethodException e) {
          } catch (Exception e) {
              System.out.println(e);
          }
      }
  
      static void checkPrivateFieldAccess() {
          (new OtherClass()).test();
      }
  
      public static void main(String[] args) throws Exception {
          Main test = new Main();
          test.run();
  
          checkGetDeclaredConstructor();
          checkAccess();
          checkSwap();
          checkClinitForFields();
          checkClinitForMethods();
          checkGeneric();
          checkUnique();
          checkParametrizedTypeEqualsAndHashCode();
          checkGenericArrayTypeEqualsAndHashCode();
          checkPrivateFieldAccess();
      }
  }
  
  
  class SuperTarget {
      public SuperTarget() {
          System.out.println("SuperTarget constructor ()V");
          superInt = 1010101;
          superClassInt = 1010102;
      }
  
      public int myMethod(float floatArg) {
          System.out.println("myMethod (F)I " + floatArg);
          return 6;
      }
  
      public int superInt;
      public static int superClassInt;
  }
  
  class Target extends SuperTarget {
      public Target() {
          System.out.println("Target constructor ()V");
      }
  
      public Target(int ii, float ff) {
          System.out.println("Target constructor (IF)V : ii="
              + ii + " ff=" + ff);
          anInt = ii;
      }
  
      public int myMethod(int intarg) throws NullPointerException, IOException {
          System.out.println("myMethod (I)I");
          System.out.println(" arg=" + intarg + " anInt=" + anInt);
          return 5;
      }
  
      public int myMethod(String[] strarg, float f, char c) {
          System.out.println("myMethod: " + strarg[0] + " " + f + " " + c + " !");
          return 7;
      }
  
      public static void myNoargMethod() {
          System.out.println("myNoargMethod ()V");
      }
  
      public void throwingMethod() {
          System.out.println("throwingMethod");
          throw new NullPointerException("gratuitous throw!");
      }
  
      public void misc() {
          System.out.println("misc");
      }
  
      public int anInt;
      public String string1 = "hey";
      public String string2 = "yo";
      public String string3 = "there";
      private String string4 = "naughty";
      public static final String constantString = "a constant string";
      private int aPrivateInt;
  
      public final int cantTouchThis = 77;
  
      public long pubLong = 0x1122334455667788L;
  
      public static double staticDouble = 3.3;
  }
  
  class FieldNoisyInit {
      static {
          System.out.println("FieldNoisyInit is initializing");
          //Throwable th = new Throwable();
          //th.printStackTrace();
      }
  }
  
  class FieldNoisyInitUser {
      static {
          System.out.println("FieldNoisyInitUser is initializing");
      }
      public static int staticField;
      public static FieldNoisyInit noisy;
  }
  
  class MethodNoisyInit {
      static {
          System.out.println("MethodNoisyInit is initializing");
          //Throwable th = new Throwable();
          //th.printStackTrace();
      }
  }
  
  class MethodNoisyInitUser {
      static {
          System.out.println("MethodNoisyInitUser is initializing");
      }
      public static void staticMethod() {}
      public void createMethodNoisyInit(MethodNoisyInit ni) {}
  }
  
  class Thrower {
      public Thrower() throws UnsupportedOperationException {
          throw new UnsupportedOperationException();
      }
  }
  
  class ParametrizedTypeTest {
      public void aMethod(Set<String> names) {}
      public void aMethodIdentical(Set<String> names) {}
  }
  
  class GenericArrayTypeTest<T> {
      public void aMethod(T[] names) {}
      public void aMethodIdentical(T[] names) {}
  }
  
  class OtherClass {
      private static final long LONG = 1234;
      public void test() {
          try {
              Field field = getClass().getDeclaredField("LONG");
              if (1234 != field.getLong(null)) {
                System.out.println("ERROR: values don't match");
              }
          } catch (Exception e) {
              System.out.println(e);
          }
      }
  }
  