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