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