blob: ae8b2f56dab471868b6780a893434e76bfe9976c [file] [log] [blame]
jeffhao5d1ac922011-09-29 17:41:15 -07001import otherpackage.OtherPackageClass;
2
Elliott Hughes00626c22013-06-14 15:04:14 -07003import java.io.Serializable;
jeffhao5d1ac922011-09-29 17:41:15 -07004import java.lang.reflect.AccessibleObject;
5import java.lang.reflect.Constructor;
6import java.lang.reflect.Field;
7import java.lang.reflect.InvocationTargetException;
8import java.lang.reflect.Method;
Elliott Hughes00626c22013-06-14 15:04:14 -07009import java.lang.reflect.Modifier;
jeffhao5d1ac922011-09-29 17:41:15 -070010import java.lang.reflect.Type;
Elliott Hughes741b5b72012-01-31 19:18:51 -080011import java.lang.reflect.TypeVariable;
jeffhao5d1ac922011-09-29 17:41:15 -070012
13public class 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
Elliott Hughes00626c22013-06-14 15:04:14 -070026 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
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
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
jeffhao5d1ac922011-09-29 17:41:15 -070089 public static void main() {
Elliott Hughes00626c22013-06-14 15:04:14 -070090 test56267();
91
jeffhao5d1ac922011-09-29 17:41:15 -070092 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
Elliott Hughes741b5b72012-01-31 19:18:51 -0800113 /* fancy */
114 printClassAttrs(FancyClass.class);
115
jeffhao5d1ac922011-09-29 17:41:15 -0700116 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 }
Elliott Hughesc1503432012-03-30 17:24:47 -0700140
141 test_isAssignableFrom();
142 test_isInstance();
143 }
144
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
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
205 private static void assertTrue(boolean b) {
206 if (!b) throw new RuntimeException();
207 }
208
209 private static void assertFalse(boolean b) {
210 if (b) throw new RuntimeException();
211 }
212
213 private static void fail() {
214 throw new RuntimeException();
jeffhao5d1ac922011-09-29 17:41:15 -0700215 }
216
217 /* to call the (out-of-scope) <code>getSignatureAttribute</code> methods */
218 public static String getSignatureAttribute(Object obj) {
219 Method method;
220 try {
Elliott Hughes32caed42011-10-06 13:41:44 -0700221 Class c = Class.forName("libcore.reflect.AnnotationAccess");
222 method = c.getDeclaredMethod("getSignature", java.lang.reflect.AnnotatedElement.class);
jeffhao5d1ac922011-09-29 17:41:15 -0700223 method.setAccessible(true);
Elliott Hughes32caed42011-10-06 13:41:44 -0700224 } catch (Exception ex) {
jeffhao5d1ac922011-09-29 17:41:15 -0700225 ex.printStackTrace();
226 return "<unknown>";
227 }
228
229 try {
Elliott Hughes32caed42011-10-06 13:41:44 -0700230 return (String) method.invoke(null, obj);
jeffhao5d1ac922011-09-29 17:41:15 -0700231 } 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
242 public MemberClass(MemberClass<XYZ> memb) {
243 mWha = memb;
244 }
245
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 */
259 public static void printClassAttrs(Class clazz) {
jeffhao5d1ac922011-09-29 17:41:15 -0700260 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());
Elliott Hughes741b5b72012-01-31 19:18:51 -0800275 System.out.println(" genericSuperclass: "
jeffhao5d1ac922011-09-29 17:41:15 -0700276 + 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
Elliott Hughes741b5b72012-01-31 19:18:51 -0800314 System.out.println(" genericInterfaces: "
jeffhao5d1ac922011-09-29 17:41:15 -0700315 + stringifyTypeArray(clazz.getGenericInterfaces()));
Elliott Hughes741b5b72012-01-31 19:18:51 -0800316
317 TypeVariable<Class<?>>[] typeParameters = clazz.getTypeParameters();
318 System.out.println(" typeParameters: "
319 + stringifyTypeArray(typeParameters));
jeffhao5d1ac922011-09-29 17:41:15 -0700320 }
321
322 /*
323 * Convert an array of Type into a string. Start with an array count.
324 */
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}