• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 import otherpackage.OtherPackageClass;
2 
3 import java.io.Serializable;
4 import java.lang.reflect.AccessibleObject;
5 import java.lang.reflect.Constructor;
6 import java.lang.reflect.Field;
7 import java.lang.reflect.InvocationTargetException;
8 import java.lang.reflect.Method;
9 import java.lang.reflect.Modifier;
10 import java.lang.reflect.Type;
11 import java.lang.reflect.TypeVariable;
12 
13 public class ClassAttrs {
ClassAttrs()14     ClassAttrs() {
15         /* local, not anonymous, not member */
16         class ConsInnerNamed {
17             public void showMe() {
18                 printClassAttrs(this.getClass());
19             }
20         }
21 
22         ConsInnerNamed cinner = new ConsInnerNamed();
23         cinner.showMe();
24     }
25 
26     public class PublicInnerClass {
27     }
28 
29     protected class ProtectedInnerClass {
30     }
31 
32     private class PrivateInnerClass {
33     }
34 
35     class PackagePrivateInnerClass {
36     }
37 
38     public interface PublicInnerInterface {
39     }
40 
41     protected interface ProtectedInnerInterface {
42     }
43 
44     private interface PrivateInnerInterface {
45     }
46 
47     interface PackagePrivateInnerInterface {
48     }
49 
showModifiers(Class<?> c)50     private static void showModifiers(Class<?> c) {
51         System.out.println(Modifier.toString(c.getModifiers()) + " " + c.getName());
52     }
53 
54     // https://code.google.com/p/android/issues/detail?id=56267
test56267()55     private static void test56267() {
56         // Primitive classes.
57         showModifiers(int.class);
58         showModifiers(int[].class);
59 
60         // Regular classes.
61         showModifiers(Object.class);
62         showModifiers(Object[].class);
63 
64         // Inner classes.
65         showModifiers(PublicInnerClass.class);
66         showModifiers(PublicInnerClass[].class);
67         showModifiers(ProtectedInnerClass.class);
68         showModifiers(ProtectedInnerClass[].class);
69         showModifiers(PrivateInnerClass.class);
70         showModifiers(PrivateInnerClass[].class);
71         showModifiers(PackagePrivateInnerClass.class);
72         showModifiers(PackagePrivateInnerClass[].class);
73 
74         // Regular interfaces.
75         showModifiers(Serializable.class);
76         showModifiers(Serializable[].class);
77 
78         // Inner interfaces.
79         showModifiers(PublicInnerInterface.class);
80         showModifiers(PublicInnerInterface[].class);
81         showModifiers(ProtectedInnerInterface.class);
82         showModifiers(ProtectedInnerInterface[].class);
83         showModifiers(PrivateInnerInterface.class);
84         showModifiers(PrivateInnerInterface[].class);
85         showModifiers(PackagePrivateInnerInterface.class);
86         showModifiers(PackagePrivateInnerInterface[].class);
87     }
88 
main()89     public static void main() {
90         test56267();
91 
92         printClassAttrs(ClassAttrs.class);
93         printClassAttrs(OtherClass.class);
94         printClassAttrs(OtherPackageClass.class);
95 
96         /* local, not anonymous, not member */
97         class InnerNamed {
98             public void showMe() {
99                 printClassAttrs(this.getClass());
100             }
101         }
102         InnerNamed inner = new InnerNamed();
103         inner.showMe();
104 
105         ClassAttrs attrs = new ClassAttrs();
106 
107         /* anonymous, not local, not member */
108         printClassAttrs((new OtherClass() { int i = 5; }).getClass());
109 
110         /* member, not anonymous, not local */
111         printClassAttrs(MemberClass.class);
112 
113         /* fancy */
114         printClassAttrs(FancyClass.class);
115 
116         try {
117             Constructor cons;
118             cons = MemberClass.class.getConstructor(
119                     new Class[] { MemberClass.class });
120             System.out.println("constructor signature: "
121                     + getSignatureAttribute(cons));
122 
123             Method meth;
124             meth = MemberClass.class.getMethod("foo", (Class[]) null);
125             System.out.println("method signature: "
126                     + getSignatureAttribute(meth));
127 
128             Field field;
129             field = MemberClass.class.getField("mWha");
130             System.out.println("field signature: "
131                     + getSignatureAttribute(field));
132         } catch (NoSuchMethodException nsme) {
133             System.err.println("FAILED: " + nsme);
134         } catch (NoSuchFieldException nsfe) {
135             System.err.println("FAILED: " + nsfe);
136         } catch (RuntimeException re) {
137             System.err.println("FAILED: " + re);
138             re.printStackTrace();
139         }
140 
141         test_isAssignableFrom();
142         test_isInstance();
143     }
144 
test_isAssignableFrom()145     private static void test_isAssignableFrom() {
146         // Can always assign to things of the same type.
147         assertTrue(String.class.isAssignableFrom(String.class));
148 
149         // Can assign any reference to java.lang.Object.
150         assertTrue(Object.class.isAssignableFrom(Object.class));
151         assertTrue(Object.class.isAssignableFrom(Class.class));
152         assertTrue(Object.class.isAssignableFrom(String.class));
153         assertFalse(Object.class.isAssignableFrom(int.class));
154         assertFalse(Object.class.isAssignableFrom(long.class));
155 
156         // Interfaces.
157         assertTrue(CharSequence.class.isAssignableFrom(String.class));
158         assertFalse(CharSequence.class.isAssignableFrom(Object.class));
159 
160         // Superclasses.
161         assertTrue(AccessibleObject.class.isAssignableFrom(Method.class));
162         assertFalse(Method.class.isAssignableFrom(AccessibleObject.class));
163 
164         // Arrays.
165         assertTrue(int[].class.isAssignableFrom(int[].class));
166         assertFalse(int[].class.isAssignableFrom(char[].class));
167         assertFalse(char[].class.isAssignableFrom(int[].class));
168         assertTrue(Object.class.isAssignableFrom(int[].class));
169         assertFalse(int[].class.isAssignableFrom(Object.class));
170 
171         try {
172             assertFalse(Object.class.isAssignableFrom(null));
173             fail();
174         } catch (NullPointerException expected) {
175         }
176     }
177 
test_isInstance()178     private static void test_isInstance() {
179         // Can always assign to things of the same type.
180         assertTrue(String.class.isInstance("hello"));
181 
182         // Can assign any reference to java.lang.Object.
183         assertTrue(Object.class.isInstance(new Object()));
184         assertTrue(Object.class.isInstance(Class.class));
185         assertTrue(Object.class.isInstance("hello"));
186 
187         // Interfaces.
188         assertTrue(CharSequence.class.isInstance("hello"));
189         assertFalse(CharSequence.class.isInstance(new Object()));
190 
191         // Superclasses.
192         assertTrue(AccessibleObject.class.isInstance(Method.class.getDeclaredMethods()[0]));
193         assertFalse(Method.class.isInstance(Method.class.getDeclaredFields()[0]));
194 
195         // Arrays.
196         assertTrue(int[].class.isInstance(new int[0]));
197         assertFalse(int[].class.isInstance(new char[0]));
198         assertFalse(char[].class.isInstance(new int[0]));
199         assertTrue(Object.class.isInstance(new int[0]));
200         assertFalse(int[].class.isInstance(new Object()));
201 
202         assertFalse(Object.class.isInstance(null));
203     }
204 
assertTrue(boolean b)205     private static void assertTrue(boolean b) {
206         if (!b) throw new RuntimeException();
207     }
208 
assertFalse(boolean b)209     private static void assertFalse(boolean b) {
210         if (b) throw new RuntimeException();
211     }
212 
fail()213     private static void fail() {
214         throw new RuntimeException();
215     }
216 
217     /* to call the (out-of-scope) <code>getSignatureAttribute</code> methods */
getSignatureAttribute(Object obj)218     public static String getSignatureAttribute(Object obj) {
219         Method method;
220         try {
221             Class c = Class.forName("libcore.reflect.AnnotationAccess");
222             method = c.getDeclaredMethod("getSignature", java.lang.reflect.AnnotatedElement.class);
223             method.setAccessible(true);
224         } catch (Exception ex) {
225             ex.printStackTrace();
226             return "<unknown>";
227         }
228 
229         try {
230             return (String) method.invoke(null, obj);
231         } catch (IllegalAccessException ex) {
232             throw new RuntimeException(ex);
233         } catch (InvocationTargetException ex) {
234             throw new RuntimeException(ex);
235         }
236     }
237 
238     /* for reflection testing */
239     static class MemberClass<XYZ> {
240         public MemberClass<XYZ> mWha;
241 
MemberClass(MemberClass<XYZ> memb)242         public MemberClass(MemberClass<XYZ> memb) {
243             mWha = memb;
244         }
245 
foo()246         public Class<XYZ> foo() throws NoSuchMethodException {
247             return null;
248         }
249     }
250 
251     /* for reflection testing (getClasses vs getDeclaredClasses) */
252     static public class PublicMemberClass {
253         float mBlah;
254     }
255 
256     /*
257      * Dump a variety of class attributes.
258      */
printClassAttrs(Class clazz)259     public static void printClassAttrs(Class clazz) {
260         Class clazz2;
261 
262         System.out.println("***** " + clazz + ":");
263 
264         System.out.println("  name: "
265             + clazz.getName());
266         System.out.println("  canonical: "
267             + clazz.getCanonicalName());
268         System.out.println("  simple: "
269             + clazz.getSimpleName());
270         System.out.println("  genericSignature: "
271             + getSignatureAttribute(clazz));
272 
273         System.out.println("  super: "
274             + clazz.getSuperclass());
275         System.out.println("  genericSuperclass: "
276             + clazz.getGenericSuperclass());
277         System.out.println("  declaring: "
278             + clazz.getDeclaringClass());
279         System.out.println("  enclosing: "
280             + clazz.getEnclosingClass());
281         System.out.println("  enclosingCon: "
282             + clazz.getEnclosingConstructor());
283         System.out.println("  enclosingMeth: "
284             + clazz.getEnclosingMethod());
285         System.out.println("  modifiers: "
286             + clazz.getModifiers());
287         System.out.println("  package: "
288             + clazz.getPackage());
289 
290         System.out.println("  declaredClasses: "
291             + stringifyTypeArray(clazz.getDeclaredClasses()));
292         System.out.println("  member classes: "
293             + stringifyTypeArray(clazz.getClasses()));
294 
295         System.out.println("  isAnnotation: "
296             + clazz.isAnnotation());
297         System.out.println("  isAnonymous: "
298             + clazz.isAnonymousClass());
299         System.out.println("  isArray: "
300             + clazz.isArray());
301         System.out.println("  isEnum: "
302             + clazz.isEnum());
303         System.out.println("  isInterface: "
304             + clazz.isInterface());
305         System.out.println("  isLocalClass: "
306             + clazz.isLocalClass());
307         System.out.println("  isMemberClass: "
308             + clazz.isMemberClass());
309         System.out.println("  isPrimitive: "
310             + clazz.isPrimitive());
311         System.out.println("  isSynthetic: "
312             + clazz.isSynthetic());
313 
314         System.out.println("  genericInterfaces: "
315             + stringifyTypeArray(clazz.getGenericInterfaces()));
316 
317         TypeVariable<Class<?>>[] typeParameters = clazz.getTypeParameters();
318         System.out.println("  typeParameters: "
319             + stringifyTypeArray(typeParameters));
320     }
321 
322     /*
323      * Convert an array of Type into a string.  Start with an array count.
324      */
stringifyTypeArray(Type[] types)325     private static String stringifyTypeArray(Type[] types) {
326         StringBuilder stb = new StringBuilder();
327         boolean first = true;
328 
329         stb.append("[" + types.length + "]");
330 
331         for (Type t: types) {
332             if (first) {
333                 stb.append(" ");
334                 first = false;
335             } else {
336                 stb.append(", ");
337             }
338             stb.append(t.toString());
339         }
340 
341         return stb.toString();
342     }
343 }
344