15d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport otherpackage.OtherPackageClass;
25d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
300626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughesimport java.io.Serializable;
45d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.AccessibleObject;
55d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Constructor;
65d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Field;
75d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.InvocationTargetException;
85d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Method;
900626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughesimport java.lang.reflect.Modifier;
105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Type;
11741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughesimport java.lang.reflect.TypeVariable;
12b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertzimport java.util.ArrayList;
13b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertzimport java.util.Collections;
14b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertzimport java.util.List;
155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class ClassAttrs {
175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    ClassAttrs() {
185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* local, not anonymous, not member */
195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        class ConsInnerNamed {
205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            public void showMe() {
215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                printClassAttrs(this.getClass());
225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        ConsInnerNamed cinner = new ConsInnerNamed();
265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        cinner.showMe();
275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2900626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    public class PublicInnerClass {
3000626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
3100626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
3200626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    protected class ProtectedInnerClass {
3300626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
3400626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
3500626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    private class PrivateInnerClass {
3600626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
3700626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
3800626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    class PackagePrivateInnerClass {
3900626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
4000626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
4100626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    public interface PublicInnerInterface {
4200626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
4300626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
4400626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    protected interface ProtectedInnerInterface {
4500626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
4600626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
4700626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    private interface PrivateInnerInterface {
4800626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
4900626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
5000626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    interface PackagePrivateInnerInterface {
5100626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
5200626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
5300626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    private static void showModifiers(Class<?> c) {
5400626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        System.out.println(Modifier.toString(c.getModifiers()) + " " + c.getName());
5500626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
5600626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
5700626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    // https://code.google.com/p/android/issues/detail?id=56267
5800626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    private static void test56267() {
5900626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        // Primitive classes.
6000626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(int.class);
6100626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(int[].class);
6200626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
6300626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        // Regular classes.
6400626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(Object.class);
6500626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(Object[].class);
6600626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
6700626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        // Inner classes.
6800626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PublicInnerClass.class);
6900626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PublicInnerClass[].class);
7000626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(ProtectedInnerClass.class);
7100626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(ProtectedInnerClass[].class);
7200626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PrivateInnerClass.class);
7300626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PrivateInnerClass[].class);
7400626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PackagePrivateInnerClass.class);
7500626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PackagePrivateInnerClass[].class);
7600626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
7700626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        // Regular interfaces.
7800626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(Serializable.class);
7900626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(Serializable[].class);
8000626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
8100626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        // Inner interfaces.
8200626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PublicInnerInterface.class);
8300626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PublicInnerInterface[].class);
8400626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(ProtectedInnerInterface.class);
8500626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(ProtectedInnerInterface[].class);
8600626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PrivateInnerInterface.class);
8700626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PrivateInnerInterface[].class);
8800626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PackagePrivateInnerInterface.class);
8900626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        showModifiers(PackagePrivateInnerInterface[].class);
9000626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes    }
9100626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void main() {
9300626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes        test56267();
9400626c2e50ba085b95f860e941d0f41eb84d4ac9Elliott Hughes
955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        printClassAttrs(ClassAttrs.class);
965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        printClassAttrs(OtherClass.class);
975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        printClassAttrs(OtherPackageClass.class);
985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* local, not anonymous, not member */
1005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        class InnerNamed {
1015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            public void showMe() {
1025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                printClassAttrs(this.getClass());
1035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
1045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        InnerNamed inner = new InnerNamed();
1065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        inner.showMe();
1075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        ClassAttrs attrs = new ClassAttrs();
1095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* anonymous, not local, not member */
1115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        printClassAttrs((new OtherClass() { int i = 5; }).getClass());
1125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* member, not anonymous, not local */
1145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        printClassAttrs(MemberClass.class);
1155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
116741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        /* fancy */
117741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        printClassAttrs(FancyClass.class);
118741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes
1195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Constructor cons;
1215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            cons = MemberClass.class.getConstructor(
1225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                    new Class[] { MemberClass.class });
1235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("constructor signature: "
1245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                    + getSignatureAttribute(cons));
1255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Method meth;
1275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            meth = MemberClass.class.getMethod("foo", (Class[]) null);
1285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("method signature: "
1295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                    + getSignatureAttribute(meth));
1305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Field field;
1325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            field = MemberClass.class.getField("mWha");
1335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("field signature: "
1345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                    + getSignatureAttribute(field));
1355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (NoSuchMethodException nsme) {
1365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("FAILED: " + nsme);
1375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (NoSuchFieldException nsfe) {
1385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("FAILED: " + nsfe);
1395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (RuntimeException re) {
1405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("FAILED: " + re);
1415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            re.printStackTrace();
1425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
143c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
144c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        test_isAssignableFrom();
145c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        test_isInstance();
146c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    }
147c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
148c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    private static void test_isAssignableFrom() {
149c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Can always assign to things of the same type.
150c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(String.class.isAssignableFrom(String.class));
151c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
152c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Can assign any reference to java.lang.Object.
153c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(Object.class.isAssignableFrom(Object.class));
154c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(Object.class.isAssignableFrom(Class.class));
155c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(Object.class.isAssignableFrom(String.class));
156c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(Object.class.isAssignableFrom(int.class));
157c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(Object.class.isAssignableFrom(long.class));
158c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
159c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Interfaces.
160c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(CharSequence.class.isAssignableFrom(String.class));
161c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(CharSequence.class.isAssignableFrom(Object.class));
162c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
163c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Superclasses.
164c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(AccessibleObject.class.isAssignableFrom(Method.class));
165c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(Method.class.isAssignableFrom(AccessibleObject.class));
166c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
167c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Arrays.
168c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(int[].class.isAssignableFrom(int[].class));
169c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(int[].class.isAssignableFrom(char[].class));
170c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(char[].class.isAssignableFrom(int[].class));
171c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(Object.class.isAssignableFrom(int[].class));
172c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(int[].class.isAssignableFrom(Object.class));
173c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
174c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        try {
175c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes            assertFalse(Object.class.isAssignableFrom(null));
176c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes            fail();
177c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        } catch (NullPointerException expected) {
178c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        }
179c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    }
180c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
181c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    private static void test_isInstance() {
182c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Can always assign to things of the same type.
183c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(String.class.isInstance("hello"));
184c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
185c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Can assign any reference to java.lang.Object.
186c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(Object.class.isInstance(new Object()));
187c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(Object.class.isInstance(Class.class));
188c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(Object.class.isInstance("hello"));
189c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
190c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Interfaces.
191c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(CharSequence.class.isInstance("hello"));
192c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(CharSequence.class.isInstance(new Object()));
193c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
194c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Superclasses.
195c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(AccessibleObject.class.isInstance(Method.class.getDeclaredMethods()[0]));
196c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(Method.class.isInstance(Method.class.getDeclaredFields()[0]));
197c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
198c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        // Arrays.
199c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(int[].class.isInstance(new int[0]));
200c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(int[].class.isInstance(new char[0]));
201c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(char[].class.isInstance(new int[0]));
202c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertTrue(Object.class.isInstance(new int[0]));
203c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(int[].class.isInstance(new Object()));
204c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
205c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        assertFalse(Object.class.isInstance(null));
206c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    }
207c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
208c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    private static void assertTrue(boolean b) {
209c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        if (!b) throw new RuntimeException();
210c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    }
211c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
212c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    private static void assertFalse(boolean b) {
213c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        if (b) throw new RuntimeException();
214c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    }
215c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes
216c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes    private static void fail() {
217c1503430c715f9d71cf4297a186a9a3442f5b9eeElliott Hughes        throw new RuntimeException();
2185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /* to call the (out-of-scope) <code>getSignatureAttribute</code> methods */
2215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static String getSignatureAttribute(Object obj) {
2225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Method method;
2235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
22432caed449e4f2ecd90ebb116a714df0ebcc537e9Elliott Hughes            Class c = Class.forName("libcore.reflect.AnnotationAccess");
22532caed449e4f2ecd90ebb116a714df0ebcc537e9Elliott Hughes            method = c.getDeclaredMethod("getSignature", java.lang.reflect.AnnotatedElement.class);
2265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            method.setAccessible(true);
22732caed449e4f2ecd90ebb116a714df0ebcc537e9Elliott Hughes        } catch (Exception ex) {
2285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ex.printStackTrace();
2295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return "<unknown>";
2305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
23332caed449e4f2ecd90ebb116a714df0ebcc537e9Elliott Hughes            return (String) method.invoke(null, obj);
2345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException ex) {
2355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            throw new RuntimeException(ex);
2365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InvocationTargetException ex) {
2375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            throw new RuntimeException(ex);
2385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /* for reflection testing */
2425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static class MemberClass<XYZ> {
2435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        public MemberClass<XYZ> mWha;
2445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        public MemberClass(MemberClass<XYZ> memb) {
2465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            mWha = memb;
2475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        public Class<XYZ> foo() throws NoSuchMethodException {
2505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return null;
2515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /* for reflection testing (getClasses vs getDeclaredClasses) */
2555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static public class PublicMemberClass {
2565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        float mBlah;
2575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /*
2605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Dump a variety of class attributes.
2615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
2625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void printClassAttrs(Class clazz) {
2635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class clazz2;
2645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("***** " + clazz + ":");
2665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  name: "
2685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getName());
2695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  canonical: "
2705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getCanonicalName());
2715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  simple: "
2725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getSimpleName());
2735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  genericSignature: "
2745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + getSignatureAttribute(clazz));
2755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  super: "
2775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getSuperclass());
278741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        System.out.println("  genericSuperclass: "
2795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getGenericSuperclass());
2805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  declaring: "
2815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getDeclaringClass());
2825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  enclosing: "
2835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getEnclosingClass());
2845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  enclosingCon: "
2855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getEnclosingConstructor());
2865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  enclosingMeth: "
2875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getEnclosingMethod());
2885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  modifiers: "
2895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getModifiers());
2905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  package: "
2915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.getPackage());
2925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  declaredClasses: "
2945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + stringifyTypeArray(clazz.getDeclaredClasses()));
2955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  member classes: "
2965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + stringifyTypeArray(clazz.getClasses()));
2975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  isAnnotation: "
2995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.isAnnotation());
3005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  isAnonymous: "
3015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.isAnonymousClass());
3025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  isArray: "
3035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.isArray());
3045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  isEnum: "
3055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.isEnum());
3065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  isInterface: "
3075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.isInterface());
3085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  isLocalClass: "
3095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.isLocalClass());
3105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  isMemberClass: "
3115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.isMemberClass());
3125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  isPrimitive: "
3135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.isPrimitive());
3145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("  isSynthetic: "
3155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + clazz.isSynthetic());
3165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
317741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        System.out.println("  genericInterfaces: "
3185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + stringifyTypeArray(clazz.getGenericInterfaces()));
319741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes
320741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        TypeVariable<Class<?>>[] typeParameters = clazz.getTypeParameters();
321741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        System.out.println("  typeParameters: "
322741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            + stringifyTypeArray(typeParameters));
3235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /*
3265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Convert an array of Type into a string.  Start with an array count.
3275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
3285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private static String stringifyTypeArray(Type[] types) {
329b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertz        List<String> typeStringList = new ArrayList<String>();
330b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertz        for (Type t : types) {
331b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertz          typeStringList.add(t.toString());
332b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertz        }
333c5e3ab2bcb90c1c5579658736ede950ef264883fSebastien Hertz        // Sort types alphabetically so they're always printed in the same order.
334c5e3ab2bcb90c1c5579658736ede950ef264883fSebastien Hertz        // For instance, Class.getClasses() does not guarantee any order for the
335c5e3ab2bcb90c1c5579658736ede950ef264883fSebastien Hertz        // returned Class[].
336b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertz        Collections.sort(typeStringList);
337b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertz
3385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        StringBuilder stb = new StringBuilder();
3395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        boolean first = true;
3405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        stb.append("[" + types.length + "]");
3425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
343b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertz        for (String typeString : typeStringList) {
3445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (first) {
3455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                stb.append(" ");
3465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                first = false;
3475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            } else {
3485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                stb.append(", ");
3495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
350b1add757fc60d8645ffa36db5bbb9279d86451eeSebastien Hertz            stb.append(typeString);
3515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return stb.toString();
3545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
356