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 13 public 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 26 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 89 public static void main() { 90 test56267(); 91 92 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 113 /* fancy */ 114 printClassAttrs(FancyClass.class); 115 116 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 } 140 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(); 215 } 216 217 /* to call the (out-of-scope) <code>getSignatureAttribute</code> methods */ 218 public static String getSignatureAttribute(Object obj) { 219 Method method; 220 try { 221 Class c = Class.forName("libcore.reflect.AnnotationAccess"); 222 method = c.getDeclaredMethod("getSignature", java.lang.reflect.AnnotatedElement.class); 223 method.setAccessible(true); 224 } catch (Exception ex) { 225 ex.printStackTrace(); 226 return "<unknown>"; 227 } 228 229 try { 230 return (String) method.invoke(null, obj); 231 } 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) { 260 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()); 275 System.out.println(" genericSuperclass: " 276 + 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 314 System.out.println(" genericInterfaces: " 315 + stringifyTypeArray(clazz.getGenericInterfaces())); 316 317 TypeVariable<Class<?>>[] typeParameters = clazz.getTypeParameters(); 318 System.out.println(" typeParameters: " 319 + stringifyTypeArray(typeParameters)); 320 } 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 } 344