Home | History | Annotate | Download | only in src
      1 import otherpackage.OtherPackageClass;
      2 
      3 import java.lang.reflect.AccessibleObject;
      4 import java.lang.reflect.Constructor;
      5 import java.lang.reflect.Field;
      6 import java.lang.reflect.InvocationTargetException;
      7 import java.lang.reflect.Method;
      8 import java.lang.reflect.Modifier;
      9 import java.lang.reflect.Type;
     10 import java.lang.reflect.TypeVariable;
     11 
     12 public class ClassAttrs {
     13     ClassAttrs() {
     14         /* local, not anonymous, not member */
     15         class ConsInnerNamed {
     16             public void showMe() {
     17                 printClassAttrs(this.getClass());
     18             }
     19         }
     20 
     21         ConsInnerNamed cinner = new ConsInnerNamed();
     22         cinner.showMe();
     23     }
     24 
     25     public class PublicInnerClass {
     26     }
     27 
     28     protected class ProtectedInnerClass {
     29     }
     30 
     31     private class PrivateInnerClass {
     32     }
     33 
     34     class PackagePrivateInnerClass {
     35     }
     36 
     37     private static void showModifiers(Class<?> c) {
     38         System.out.println(Modifier.toString(c.getModifiers()) + " " + c.getName());
     39     }
     40 
     41     // https://code.google.com/p/android/issues/detail?id=56267
     42     private static void test56267() {
     43         // Primitive classes.
     44         showModifiers(int.class);
     45         showModifiers(int[].class);
     46 
     47         // Regular classes.
     48         showModifiers(Object.class);
     49         showModifiers(Object[].class);
     50 
     51         // Inner classes.
     52         showModifiers(PublicInnerClass.class);
     53         showModifiers(PublicInnerClass[].class);
     54         showModifiers(ProtectedInnerClass.class);
     55         showModifiers(ProtectedInnerClass[].class);
     56         showModifiers(PrivateInnerClass.class);
     57         showModifiers(PrivateInnerClass[].class);
     58         showModifiers(PackagePrivateInnerClass.class);
     59         showModifiers(PackagePrivateInnerClass[].class);
     60     }
     61 
     62     public static void main() {
     63         test56267();
     64 
     65         printClassAttrs(ClassAttrs.class);
     66         printClassAttrs(OtherClass.class);
     67         printClassAttrs(OtherPackageClass.class);
     68 
     69         /* local, not anonymous, not member */
     70         class InnerNamed {
     71             public void showMe() {
     72                 printClassAttrs(this.getClass());
     73             }
     74         }
     75         InnerNamed inner = new InnerNamed();
     76         inner.showMe();
     77 
     78         ClassAttrs attrs = new ClassAttrs();
     79 
     80         /* anonymous, not local, not member */
     81         printClassAttrs((new OtherClass() { int i = 5; }).getClass());
     82 
     83         /* member, not anonymous, not local */
     84         printClassAttrs(MemberClass.class);
     85 
     86         /* fancy */
     87         printClassAttrs(FancyClass.class);
     88 
     89         try {
     90             Constructor cons;
     91             cons = MemberClass.class.getConstructor(
     92                     new Class[] { MemberClass.class });
     93             System.out.println("constructor signature: "
     94                     + getSignatureAttribute(cons));
     95 
     96             Method meth;
     97             meth = MemberClass.class.getMethod("foo", (Class[]) null);
     98             System.out.println("method signature: "
     99                     + getSignatureAttribute(meth));
    100 
    101             Field field;
    102             field = MemberClass.class.getField("mWha");
    103             System.out.println("field signature: "
    104                     + getSignatureAttribute(field));
    105         } catch (NoSuchMethodException nsme) {
    106             System.err.println("FAILED: " + nsme);
    107         } catch (NoSuchFieldException nsfe) {
    108             System.err.println("FAILED: " + nsfe);
    109         } catch (RuntimeException re) {
    110             System.err.println("FAILED: " + re);
    111             re.printStackTrace();
    112         }
    113     }
    114 
    115     /* to call the (out-of-scope) <code>getSignatureAttribute</code> methods */
    116     public static String getSignatureAttribute(Object obj) {
    117         Method method;
    118         try {
    119             if (obj instanceof AccessibleObject) {
    120                 method = AccessibleObject.class.getDeclaredMethod(
    121                         "getSignatureAttribute");
    122             } else {
    123                 // Should be a Class.
    124                 method = Class.class.getDeclaredMethod(
    125                         "getSignatureAttribute");
    126             }
    127             method.setAccessible(true);
    128         } catch (NoSuchMethodException ex) {
    129             //System.err.println("getSignatureAttribute() not defined.");
    130             //ex.printStackTrace();
    131             return "<unknown>";
    132         }
    133 
    134         try {
    135             return (String) method.invoke(obj);
    136         } catch (IllegalAccessException ex) {
    137             throw new RuntimeException(ex);
    138         } catch (InvocationTargetException ex) {
    139             throw new RuntimeException(ex);
    140         }
    141     }
    142 
    143     /* for reflection testing */
    144     static class MemberClass<XYZ> {
    145         public MemberClass<XYZ> mWha;
    146 
    147         public MemberClass(MemberClass<XYZ> memb) {
    148             mWha = memb;
    149         }
    150 
    151         public Class<XYZ> foo() throws NoSuchMethodException {
    152             return null;
    153         }
    154     }
    155 
    156     /* for reflection testing (getClasses vs getDeclaredClasses) */
    157     static public class PublicMemberClass {
    158         float mBlah;
    159     }
    160 
    161     /*
    162      * Dump a variety of class attributes.
    163      */
    164     public static void printClassAttrs(Class clazz) {
    165         Class clazz2;
    166 
    167         System.out.println("***** " + clazz + ":");
    168 
    169         System.out.println("  name: "
    170             + clazz.getName());
    171         System.out.println("  canonical: "
    172             + clazz.getCanonicalName());
    173         System.out.println("  simple: "
    174             + clazz.getSimpleName());
    175         System.out.println("  genericSignature: "
    176             + getSignatureAttribute(clazz));
    177 
    178         System.out.println("  super: "
    179             + clazz.getSuperclass());
    180         System.out.println("  genericSuperclass: "
    181             + clazz.getGenericSuperclass());
    182         System.out.println("  declaring: "
    183             + clazz.getDeclaringClass());
    184         System.out.println("  enclosing: "
    185             + clazz.getEnclosingClass());
    186         System.out.println("  enclosingCon: "
    187             + clazz.getEnclosingConstructor());
    188         System.out.println("  enclosingMeth: "
    189             + clazz.getEnclosingMethod());
    190         System.out.println("  modifiers: "
    191             + clazz.getModifiers());
    192         System.out.println("  package: "
    193             + clazz.getPackage());
    194 
    195         System.out.println("  declaredClasses: "
    196             + stringifyTypeArray(clazz.getDeclaredClasses()));
    197         System.out.println("  member classes: "
    198             + stringifyTypeArray(clazz.getClasses()));
    199 
    200         System.out.println("  isAnnotation: "
    201             + clazz.isAnnotation());
    202         System.out.println("  isAnonymous: "
    203             + clazz.isAnonymousClass());
    204         System.out.println("  isArray: "
    205             + clazz.isArray());
    206         System.out.println("  isEnum: "
    207             + clazz.isEnum());
    208         System.out.println("  isInterface: "
    209             + clazz.isInterface());
    210         System.out.println("  isLocalClass: "
    211             + clazz.isLocalClass());
    212         System.out.println("  isMemberClass: "
    213             + clazz.isMemberClass());
    214         System.out.println("  isPrimitive: "
    215             + clazz.isPrimitive());
    216         System.out.println("  isSynthetic: "
    217             + clazz.isSynthetic());
    218 
    219         System.out.println("  genericInterfaces: "
    220             + stringifyTypeArray(clazz.getGenericInterfaces()));
    221 
    222         TypeVariable<Class<?>>[] typeParameters = clazz.getTypeParameters();
    223         System.out.println("  typeParameters: "
    224             + stringifyTypeArray(typeParameters));
    225     }
    226 
    227     /*
    228      * Convert an array of Type into a string.  Start with an array count.
    229      */
    230     private static String stringifyTypeArray(Type[] types) {
    231         StringBuilder stb = new StringBuilder();
    232         boolean first = true;
    233 
    234         stb.append("[" + types.length + "]");
    235 
    236         for (Type t: types) {
    237             if (first) {
    238                 stb.append(" ");
    239                 first = false;
    240             } else {
    241                 stb.append(", ");
    242             }
    243             stb.append(t.toString());
    244         }
    245 
    246         return stb.toString();
    247     }
    248 }
    249