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 import java.util.ArrayList; 13 import java.util.Collections; 14 import java.util.List; 15 16 public class ClassAttrs { ClassAttrs()17 ClassAttrs() { 18 /* local, not anonymous, not member */ 19 class ConsInnerNamed { 20 public void showMe() { 21 printClassAttrs(this.getClass()); 22 } 23 } 24 25 ConsInnerNamed cinner = new ConsInnerNamed(); 26 cinner.showMe(); 27 } 28 29 public class PublicInnerClass { 30 } 31 32 protected class ProtectedInnerClass { 33 } 34 35 private class PrivateInnerClass { 36 } 37 38 class PackagePrivateInnerClass { 39 } 40 41 public interface PublicInnerInterface { 42 } 43 44 protected interface ProtectedInnerInterface { 45 } 46 47 private interface PrivateInnerInterface { 48 } 49 50 interface PackagePrivateInnerInterface { 51 } 52 showModifiers(Class<?> c)53 private static void showModifiers(Class<?> c) { 54 System.out.println(Modifier.toString(c.getModifiers()) + " " + c.getName()); 55 } 56 57 // https://code.google.com/p/android/issues/detail?id=56267 test56267()58 private static void test56267() { 59 // Primitive classes. 60 showModifiers(int.class); 61 showModifiers(int[].class); 62 63 // Regular classes. 64 showModifiers(Object.class); 65 showModifiers(Object[].class); 66 67 // Inner classes. 68 showModifiers(PublicInnerClass.class); 69 showModifiers(PublicInnerClass[].class); 70 showModifiers(ProtectedInnerClass.class); 71 showModifiers(ProtectedInnerClass[].class); 72 showModifiers(PrivateInnerClass.class); 73 showModifiers(PrivateInnerClass[].class); 74 showModifiers(PackagePrivateInnerClass.class); 75 showModifiers(PackagePrivateInnerClass[].class); 76 77 // Regular interfaces. 78 showModifiers(Serializable.class); 79 showModifiers(Serializable[].class); 80 81 // Inner interfaces. 82 showModifiers(PublicInnerInterface.class); 83 showModifiers(PublicInnerInterface[].class); 84 showModifiers(ProtectedInnerInterface.class); 85 showModifiers(ProtectedInnerInterface[].class); 86 showModifiers(PrivateInnerInterface.class); 87 showModifiers(PrivateInnerInterface[].class); 88 showModifiers(PackagePrivateInnerInterface.class); 89 showModifiers(PackagePrivateInnerInterface[].class); 90 } 91 main()92 public static void main() { 93 test56267(); 94 95 printClassAttrs(ClassAttrs.class); 96 printClassAttrs(OtherClass.class); 97 printClassAttrs(OtherPackageClass.class); 98 99 /* local, not anonymous, not member */ 100 class InnerNamed { 101 public void showMe() { 102 printClassAttrs(this.getClass()); 103 } 104 } 105 InnerNamed inner = new InnerNamed(); 106 inner.showMe(); 107 108 ClassAttrs attrs = new ClassAttrs(); 109 110 /* anonymous, not local, not member */ 111 printClassAttrs((new OtherClass() { int i = 5; }).getClass()); 112 113 /* member, not anonymous, not local */ 114 printClassAttrs(MemberClass.class); 115 116 /* fancy */ 117 printClassAttrs(FancyClass.class); 118 119 try { 120 Constructor cons; 121 cons = MemberClass.class.getConstructor( 122 new Class[] { MemberClass.class }); 123 System.out.println("constructor signature: " 124 + getSignatureAttribute(cons)); 125 126 Method meth; 127 meth = MemberClass.class.getMethod("foo", (Class[]) null); 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 = Class.forName("libcore.reflect.AnnotationAccess"); 225 method = c.getDeclaredMethod("getSignature", java.lang.reflect.AnnotatedElement.class); 226 method.setAccessible(true); 227 } catch (Exception ex) { 228 ex.printStackTrace(); 229 return "<unknown>"; 230 } 231 232 try { 233 return (String) method.invoke(null, obj); 234 } catch (IllegalAccessException ex) { 235 throw new RuntimeException(ex); 236 } catch (InvocationTargetException ex) { 237 throw new RuntimeException(ex); 238 } 239 } 240 241 /* for reflection testing */ 242 static class MemberClass<XYZ> { 243 public MemberClass<XYZ> mWha; 244 MemberClass(MemberClass<XYZ> memb)245 public MemberClass(MemberClass<XYZ> memb) { 246 mWha = memb; 247 } 248 foo()249 public Class<XYZ> foo() throws NoSuchMethodException { 250 return null; 251 } 252 } 253 254 /* for reflection testing (getClasses vs getDeclaredClasses) */ 255 static public class PublicMemberClass { 256 float mBlah; 257 } 258 259 /* 260 * Dump a variety of class attributes. 261 */ printClassAttrs(Class clazz)262 public static void printClassAttrs(Class clazz) { 263 Class clazz2; 264 265 System.out.println("***** " + clazz + ":"); 266 267 System.out.println(" name: " 268 + clazz.getName()); 269 System.out.println(" canonical: " 270 + clazz.getCanonicalName()); 271 System.out.println(" simple: " 272 + clazz.getSimpleName()); 273 System.out.println(" genericSignature: " 274 + getSignatureAttribute(clazz)); 275 276 System.out.println(" super: " 277 + clazz.getSuperclass()); 278 System.out.println(" genericSuperclass: " 279 + clazz.getGenericSuperclass()); 280 System.out.println(" declaring: " 281 + clazz.getDeclaringClass()); 282 System.out.println(" enclosing: " 283 + clazz.getEnclosingClass()); 284 System.out.println(" enclosingCon: " 285 + clazz.getEnclosingConstructor()); 286 System.out.println(" enclosingMeth: " 287 + clazz.getEnclosingMethod()); 288 System.out.println(" modifiers: " 289 + clazz.getModifiers()); 290 System.out.println(" package: " 291 + clazz.getPackage()); 292 293 System.out.println(" declaredClasses: " 294 + stringifyTypeArray(clazz.getDeclaredClasses())); 295 System.out.println(" member classes: " 296 + stringifyTypeArray(clazz.getClasses())); 297 298 System.out.println(" isAnnotation: " 299 + clazz.isAnnotation()); 300 System.out.println(" isAnonymous: " 301 + clazz.isAnonymousClass()); 302 System.out.println(" isArray: " 303 + clazz.isArray()); 304 System.out.println(" isEnum: " 305 + clazz.isEnum()); 306 System.out.println(" isInterface: " 307 + clazz.isInterface()); 308 System.out.println(" isLocalClass: " 309 + clazz.isLocalClass()); 310 System.out.println(" isMemberClass: " 311 + clazz.isMemberClass()); 312 System.out.println(" isPrimitive: " 313 + clazz.isPrimitive()); 314 System.out.println(" isSynthetic: " 315 + clazz.isSynthetic()); 316 317 System.out.println(" genericInterfaces: " 318 + stringifyTypeArray(clazz.getGenericInterfaces())); 319 320 TypeVariable<Class<?>>[] typeParameters = clazz.getTypeParameters(); 321 System.out.println(" typeParameters: " 322 + stringifyTypeArray(typeParameters)); 323 } 324 325 /* 326 * Convert an array of Type into a string. Start with an array count. 327 */ stringifyTypeArray(Type[] types)328 private static String stringifyTypeArray(Type[] types) { 329 List<String> typeStringList = new ArrayList<String>(); 330 for (Type t : types) { 331 typeStringList.add(t.toString()); 332 } 333 // Sort types alphabetically so they're always printed in the same order. 334 // For instance, Class.getClasses() does not guarantee any order for the 335 // returned Class[]. 336 Collections.sort(typeStringList); 337 338 StringBuilder stb = new StringBuilder(); 339 boolean first = true; 340 341 stb.append("[" + types.length + "]"); 342 343 for (String typeString : typeStringList) { 344 if (first) { 345 stb.append(" "); 346 first = false; 347 } else { 348 stb.append(", "); 349 } 350 stb.append(typeString); 351 } 352 353 return stb.toString(); 354 } 355 } 356