• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 import otherpackage.OtherPackageClass;
2 
3 import java.io.Serializable;
4 import java.lang.reflect.AbstractMethod;
5 import java.lang.reflect.AccessibleObject;
6 import java.lang.reflect.Constructor;
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(
123                     new Class[] { MemberClass.class });
124             System.out.println("constructor signature: "
125                     + getSignatureAttribute(cons));
126 
127             Method meth;
128             meth = MemberClass.class.getMethod("foo", (Class[]) null);
129             System.out.println("method signature: "
130                     + getSignatureAttribute(meth));
131 
132             Field field;
133             field = MemberClass.class.getField("mWha");
134             System.out.println("field signature: "
135                     + getSignatureAttribute(field));
136         } catch (NoSuchMethodException nsme) {
137             System.err.println("FAILED: " + nsme);
138         } catch (NoSuchFieldException nsfe) {
139             System.err.println("FAILED: " + nsfe);
140         } catch (RuntimeException re) {
141             System.err.println("FAILED: " + re);
142             re.printStackTrace();
143         }
144 
145         test_isAssignableFrom();
146         test_isInstance();
147     }
148 
test_isAssignableFrom()149     private static void test_isAssignableFrom() {
150         // Can always assign to things of the same type.
151         assertTrue(String.class.isAssignableFrom(String.class));
152 
153         // Can assign any reference to java.lang.Object.
154         assertTrue(Object.class.isAssignableFrom(Object.class));
155         assertTrue(Object.class.isAssignableFrom(Class.class));
156         assertTrue(Object.class.isAssignableFrom(String.class));
157         assertFalse(Object.class.isAssignableFrom(int.class));
158         assertFalse(Object.class.isAssignableFrom(long.class));
159 
160         // Interfaces.
161         assertTrue(CharSequence.class.isAssignableFrom(String.class));
162         assertFalse(CharSequence.class.isAssignableFrom(Object.class));
163 
164         // Superclasses.
165         assertTrue(AccessibleObject.class.isAssignableFrom(Method.class));
166         assertFalse(Method.class.isAssignableFrom(AccessibleObject.class));
167 
168         // Arrays.
169         assertTrue(int[].class.isAssignableFrom(int[].class));
170         assertFalse(int[].class.isAssignableFrom(char[].class));
171         assertFalse(char[].class.isAssignableFrom(int[].class));
172         assertTrue(Object.class.isAssignableFrom(int[].class));
173         assertFalse(int[].class.isAssignableFrom(Object.class));
174 
175         try {
176             assertFalse(Object.class.isAssignableFrom(null));
177             fail();
178         } catch (NullPointerException expected) {
179         }
180     }
181 
test_isInstance()182     private static void test_isInstance() {
183         // Can always assign to things of the same type.
184         assertTrue(String.class.isInstance("hello"));
185 
186         // Can assign any reference to java.lang.Object.
187         assertTrue(Object.class.isInstance(new Object()));
188         assertTrue(Object.class.isInstance(Class.class));
189         assertTrue(Object.class.isInstance("hello"));
190 
191         // Interfaces.
192         assertTrue(CharSequence.class.isInstance("hello"));
193         assertFalse(CharSequence.class.isInstance(new Object()));
194 
195         // Superclasses.
196         assertTrue(AccessibleObject.class.isInstance(Method.class.getDeclaredMethods()[0]));
197         assertFalse(Method.class.isInstance(Method.class.getDeclaredFields()[0]));
198 
199         // Arrays.
200         assertTrue(int[].class.isInstance(new int[0]));
201         assertFalse(int[].class.isInstance(new char[0]));
202         assertFalse(char[].class.isInstance(new int[0]));
203         assertTrue(Object.class.isInstance(new int[0]));
204         assertFalse(int[].class.isInstance(new Object()));
205 
206         assertFalse(Object.class.isInstance(null));
207     }
208 
assertTrue(boolean b)209     private static void assertTrue(boolean b) {
210         if (!b) throw new RuntimeException();
211     }
212 
assertFalse(boolean b)213     private static void assertFalse(boolean b) {
214         if (b) throw new RuntimeException();
215     }
216 
fail()217     private static void fail() {
218         throw new RuntimeException();
219     }
220 
221     /* to call the (out-of-scope) <code>getSignatureAttribute</code> methods */
getSignatureAttribute(Object obj)222     public static String getSignatureAttribute(Object obj) {
223         Method method;
224         try {
225             Class c = obj.getClass();
226             if (c == Method.class || c == Constructor.class) {
227               c = AbstractMethod.class;
228             }
229             method = c.getDeclaredMethod("getSignatureAttribute");
230             method.setAccessible(true);
231         } catch (Exception ex) {
232             ex.printStackTrace();
233             return "<unknown>";
234         }
235 
236         try {
237             return (String) method.invoke(obj);
238         } catch (IllegalAccessException ex) {
239             throw new RuntimeException(ex);
240         } catch (InvocationTargetException ex) {
241             throw new RuntimeException(ex);
242         }
243     }
244 
245     /* for reflection testing */
246     static class MemberClass<XYZ> {
247         public MemberClass<XYZ> mWha;
248 
MemberClass(MemberClass<XYZ> memb)249         public MemberClass(MemberClass<XYZ> memb) {
250             mWha = memb;
251         }
252 
foo()253         public Class<XYZ> foo() throws NoSuchMethodException {
254             return null;
255         }
256     }
257 
258     /* for reflection testing (getClasses vs getDeclaredClasses) */
259     static public class PublicMemberClass {
260         float mBlah;
261     }
262 
263     /*
264      * Dump a variety of class attributes.
265      */
printClassAttrs(Class clazz)266     public static void printClassAttrs(Class clazz) {
267         Class clazz2;
268 
269         System.out.println("***** " + clazz + ":");
270 
271         System.out.println("  name: "
272             + clazz.getName());
273         System.out.println("  canonical: "
274             + clazz.getCanonicalName());
275         System.out.println("  simple: "
276             + clazz.getSimpleName());
277         System.out.println("  genericSignature: "
278             + getSignatureAttribute(clazz));
279 
280         System.out.println("  super: "
281             + clazz.getSuperclass());
282         System.out.println("  genericSuperclass: "
283             + clazz.getGenericSuperclass());
284         System.out.println("  declaring: "
285             + clazz.getDeclaringClass());
286         System.out.println("  enclosing: "
287             + clazz.getEnclosingClass());
288         System.out.println("  enclosingCon: "
289             + clazz.getEnclosingConstructor());
290         System.out.println("  enclosingMeth: "
291             + clazz.getEnclosingMethod());
292         System.out.println("  modifiers: "
293             + clazz.getModifiers());
294         System.out.println("  package: "
295             + clazz.getPackage());
296 
297         System.out.println("  declaredClasses: "
298             + stringifyTypeArray(clazz.getDeclaredClasses()));
299         System.out.println("  member classes: "
300             + stringifyTypeArray(clazz.getClasses()));
301 
302         System.out.println("  isAnnotation: "
303             + clazz.isAnnotation());
304         System.out.println("  isAnonymous: "
305             + clazz.isAnonymousClass());
306         System.out.println("  isArray: "
307             + clazz.isArray());
308         System.out.println("  isEnum: "
309             + clazz.isEnum());
310         System.out.println("  isInterface: "
311             + clazz.isInterface());
312         System.out.println("  isLocalClass: "
313             + clazz.isLocalClass());
314         System.out.println("  isMemberClass: "
315             + clazz.isMemberClass());
316         System.out.println("  isPrimitive: "
317             + clazz.isPrimitive());
318         System.out.println("  isSynthetic: "
319             + clazz.isSynthetic());
320 
321         System.out.println("  genericInterfaces: "
322             + stringifyTypeArray(clazz.getGenericInterfaces()));
323 
324         TypeVariable<Class<?>>[] typeParameters = clazz.getTypeParameters();
325         System.out.println("  typeParameters: "
326             + stringifyTypeArray(typeParameters));
327     }
328 
329     /*
330      * Convert an array of Type into a string.  Start with an array count.
331      */
stringifyTypeArray(Type[] types)332     private static String stringifyTypeArray(Type[] types) {
333         List<String> typeStringList = new ArrayList<String>();
334         for (Type t : types) {
335           typeStringList.add(t.toString());
336         }
337         // Sort types alphabetically so they're always printed in the same order.
338         // For instance, Class.getClasses() does not guarantee any order for the
339         // returned Class[].
340         Collections.sort(typeStringList);
341 
342         StringBuilder stb = new StringBuilder();
343         boolean first = true;
344 
345         stb.append("[" + types.length + "]");
346 
347         for (String typeString : typeStringList) {
348             if (first) {
349                 stb.append(" ");
350                 first = false;
351             } else {
352                 stb.append(", ");
353             }
354             stb.append(typeString);
355         }
356 
357         return stb.toString();
358     }
359 }
360