28 import java.lang.reflect.AnnotatedElement;
29 import java.lang.reflect.Array;
30 import java.lang.reflect.GenericArrayType;
31 import java.lang.reflect.GenericDeclaration;
32 import java.lang.reflect.Member;
33 import java.lang.reflect.Field;
34 import java.lang.reflect.Executable;
35 import java.lang.reflect.Method;
36 import java.lang.reflect.Constructor;
37 import java.lang.reflect.Modifier;
38 import java.lang.reflect.Type;
39 import java.lang.reflect.TypeVariable;
40 import java.lang.reflect.InvocationTargetException;
41 import java.lang.reflect.AnnotatedType;
42 import java.lang.ref.SoftReference;
43 import java.io.InputStream;
44 import java.io.ObjectStreamField;
45 import java.security.AccessController;
46 import java.security.PrivilegedAction;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collection;
50 import java.util.HashSet;
51 import java.util.LinkedHashMap;
52 import java.util.List;
53 import java.util.Set;
54 import java.util.Map;
55 import java.util.HashMap;
56 import java.util.Objects;
57 import java.util.StringJoiner;
58 import sun.misc.Unsafe;
59 import sun.reflect.CallerSensitive;
60 import sun.reflect.ConstantPool;
61 import sun.reflect.Reflection;
62 import sun.reflect.ReflectionFactory;
63 import sun.reflect.generics.factory.CoreReflectionFactory;
64 import sun.reflect.generics.factory.GenericsFactory;
65 import sun.reflect.generics.repository.ClassRepository;
66 import sun.reflect.generics.repository.MethodRepository;
67 import sun.reflect.generics.repository.ConstructorRepository;
68 import sun.reflect.generics.scope.ClassScope;
394 @CallerSensitive
395 public T newInstance()
396 throws InstantiationException, IllegalAccessException
397 {
398 if (System.getSecurityManager() != null) {
399 checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
400 }
401
402 // NOTE: the following code may not be strictly correct under
403 // the current Java memory model.
404
405 // Constructor lookup
406 if (cachedConstructor == null) {
407 if (this == Class.class) {
408 throw new IllegalAccessException(
409 "Can not call newInstance() on the Class for java.lang.Class"
410 );
411 }
412 try {
413 Class<?>[] empty = {};
414 final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
415 // Disable accessibility checks on the constructor
416 // since we have to do the security check here anyway
417 // (the stack depth is wrong for the Constructor's
418 // security check to work)
419 java.security.AccessController.doPrivileged(
420 new java.security.PrivilegedAction<Void>() {
421 public Void run() {
422 c.setAccessible(true);
423 return null;
424 }
425 });
426 cachedConstructor = c;
427 } catch (NoSuchMethodException e) {
428 throw (InstantiationException)
429 new InstantiationException(getName()).initCause(e);
430 }
431 }
432 Constructor<T> tmpConstructor = cachedConstructor;
433 // Security check (same as in java.lang.reflect.Constructor)
434 int modifiers = tmpConstructor.getModifiers();
825 *
826 * <p>If this object represents an interface, the array contains objects
827 * representing all interfaces directly extended by the interface. The
828 * order of the interface objects in the array corresponds to the order of
829 * the interface names in the {@code extends} clause of the declaration of
830 * the interface represented by this object.
831 *
832 * <p>If this object represents a class or interface that implements no
833 * interfaces, the method returns an array of length 0.
834 *
835 * <p>If this object represents a primitive type or void, the method
836 * returns an array of length 0.
837 *
838 * <p>If this {@code Class} object represents an array type, the
839 * interfaces {@code Cloneable} and {@code java.io.Serializable} are
840 * returned in that order.
841 *
842 * @return an array of interfaces directly implemented by this class
843 */
844 public Class<?>[] getInterfaces() {
845 ReflectionData<T> rd = reflectionData();
846 if (rd == null) {
847 // no cloning required
848 return getInterfaces0();
849 } else {
850 Class<?>[] interfaces = rd.interfaces;
851 if (interfaces == null) {
852 interfaces = getInterfaces0();
853 rd.interfaces = interfaces;
854 }
855 // defensively copy before handing over to user code
856 return interfaces.clone();
857 }
858 }
859
860 private native Class<?>[] getInterfaces0();
861
862 /**
863 * Returns the {@code Type}s representing the interfaces
864 * directly implemented by the class or interface represented by
865 * this object.
866 *
867 * <p>If a superinterface is a parameterized type, the
868 * {@code Type} object returned for it must accurately reflect
869 * the actual type parameters used in the source code. The
870 * parameterized type representing each superinterface is created
871 * if it had not been created before. See the declaration of
872 * {@link java.lang.reflect.ParameterizedType ParameterizedType}
873 * for the semantics of the creation process for parameterized
874 * types.
875 *
876 * <p>If this object represents a class, the return value is an array
1693 * @throws SecurityException
1694 * If a security manager, <i>s</i>, is present and
1695 * the caller's class loader is not the same as or an
1696 * ancestor of the class loader for the current class and
1697 * invocation of {@link SecurityManager#checkPackageAccess
1698 * s.checkPackageAccess()} denies access to the package
1699 * of this class.
1700 *
1701 * @since 1.1
1702 * @jls 8.2 Class Members
1703 * @jls 8.3 Field Declarations
1704 */
1705 @CallerSensitive
1706 public Field getField(String name)
1707 throws NoSuchFieldException, SecurityException {
1708 checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
1709 Field field = getField0(name);
1710 if (field == null) {
1711 throw new NoSuchFieldException(name);
1712 }
1713 return field;
1714 }
1715
1716
1717 /**
1718 * Returns a {@code Method} object that reflects the specified public
1719 * member method of the class or interface represented by this
1720 * {@code Class} object. The {@code name} parameter is a
1721 * {@code String} specifying the simple name of the desired method. The
1722 * {@code parameterTypes} parameter is an array of {@code Class}
1723 * objects that identify the method's formal parameter types, in declared
1724 * order. If {@code parameterTypes} is {@code null}, it is
1725 * treated as if it were an empty array.
1726 *
1727 * <p> If the {@code name} is "{@code <init>}" or "{@code <clinit>}" a
1728 * {@code NoSuchMethodException} is raised. Otherwise, the method to
1729 * be reflected is determined by the algorithm that follows. Let C be the
1730 * class or interface represented by this object:
1731 * <OL>
1732 * <LI> C is searched for a <I>matching method</I>, as defined below. If a
1733 * matching method is found, it is reflected.</LI>
1776 * @throws SecurityException
1777 * If a security manager, <i>s</i>, is present and
1778 * the caller's class loader is not the same as or an
1779 * ancestor of the class loader for the current class and
1780 * invocation of {@link SecurityManager#checkPackageAccess
1781 * s.checkPackageAccess()} denies access to the package
1782 * of this class.
1783 *
1784 * @jls 8.2 Class Members
1785 * @jls 8.4 Method Declarations
1786 * @since 1.1
1787 */
1788 @CallerSensitive
1789 public Method getMethod(String name, Class<?>... parameterTypes)
1790 throws NoSuchMethodException, SecurityException {
1791 checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
1792 Method method = getMethod0(name, parameterTypes, true);
1793 if (method == null) {
1794 throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
1795 }
1796 return method;
1797 }
1798
1799
1800 /**
1801 * Returns a {@code Constructor} object that reflects the specified
1802 * public constructor of the class represented by this {@code Class}
1803 * object. The {@code parameterTypes} parameter is an array of
1804 * {@code Class} objects that identify the constructor's formal
1805 * parameter types, in declared order.
1806 *
1807 * If this {@code Class} object represents an inner class
1808 * declared in a non-static context, the formal parameter types
1809 * include the explicit enclosing instance as the first parameter.
1810 *
1811 * <p> The constructor to reflect is the public constructor of the class
1812 * represented by this {@code Class} object whose formal parameter
1813 * types match those specified by {@code parameterTypes}.
1814 *
1815 * @param parameterTypes the parameter array
1816 * @return the {@code Constructor} object of the public constructor that
1817 * matches the specified {@code parameterTypes}
1818 * @throws NoSuchMethodException if a matching method is not found.
1819 * @throws SecurityException
1820 * If a security manager, <i>s</i>, is present and
1821 * the caller's class loader is not the same as or an
1822 * ancestor of the class loader for the current class and
1823 * invocation of {@link SecurityManager#checkPackageAccess
1824 * s.checkPackageAccess()} denies access to the package
1825 * of this class.
1826 *
1827 * @since 1.1
1828 */
1829 @CallerSensitive
1830 public Constructor<T> getConstructor(Class<?>... parameterTypes)
1831 throws NoSuchMethodException, SecurityException {
1832 checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
1833 return getConstructor0(parameterTypes, Member.PUBLIC);
1834 }
1835
1836
1837 /**
1838 * Returns an array of {@code Class} objects reflecting all the
1839 * classes and interfaces declared as members of the class represented by
1840 * this {@code Class} object. This includes public, protected, default
1841 * (package) access, and private classes and interfaces declared by the
1842 * class, but excludes inherited classes and interfaces. This method
1843 * returns an array of length 0 if the class declares no classes or
1844 * interfaces as members, or if this {@code Class} object represents a
1845 * primitive type, an array class, or void.
1846 *
1847 * @return the array of {@code Class} objects representing all the
1848 * declared members of this class
1849 * @throws SecurityException
1850 * If a security manager, <i>s</i>, is present and any of the
1851 * following conditions is met:
1852 *
1853 * <ul>
2060 * <li> the caller's class loader is not the same as or an
2061 * ancestor of the class loader for the current class and
2062 * invocation of {@link SecurityManager#checkPackageAccess
2063 * s.checkPackageAccess()} denies access to the package
2064 * of this class
2065 *
2066 * </ul>
2067 *
2068 * @since 1.1
2069 * @jls 8.2 Class Members
2070 * @jls 8.3 Field Declarations
2071 */
2072 @CallerSensitive
2073 public Field getDeclaredField(String name)
2074 throws NoSuchFieldException, SecurityException {
2075 checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
2076 Field field = searchFields(privateGetDeclaredFields(false), name);
2077 if (field == null) {
2078 throw new NoSuchFieldException(name);
2079 }
2080 return field;
2081 }
2082
2083
2084 /**
2085 * Returns a {@code Method} object that reflects the specified
2086 * declared method of the class or interface represented by this
2087 * {@code Class} object. The {@code name} parameter is a
2088 * {@code String} that specifies the simple name of the desired
2089 * method, and the {@code parameterTypes} parameter is an array of
2090 * {@code Class} objects that identify the method's formal parameter
2091 * types, in declared order. If more than one method with the same
2092 * parameter types is declared in a class, and one of these methods has a
2093 * return type that is more specific than any of the others, that method is
2094 * returned; otherwise one of the methods is chosen arbitrarily. If the
2095 * name is "<init>"or "<clinit>" a {@code NoSuchMethodException}
2096 * is raised.
2097 *
2098 * <p> If this {@code Class} object represents an array type, then this
2099 * method does not find the {@code clone()} method.
2100 *
2120 * <li> the caller's class loader is not the same as or an
2121 * ancestor of the class loader for the current class and
2122 * invocation of {@link SecurityManager#checkPackageAccess
2123 * s.checkPackageAccess()} denies access to the package
2124 * of this class
2125 *
2126 * </ul>
2127 *
2128 * @jls 8.2 Class Members
2129 * @jls 8.4 Method Declarations
2130 * @since 1.1
2131 */
2132 @CallerSensitive
2133 public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
2134 throws NoSuchMethodException, SecurityException {
2135 checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
2136 Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
2137 if (method == null) {
2138 throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
2139 }
2140 return method;
2141 }
2142
2143
2144 /**
2145 * Returns a {@code Constructor} object that reflects the specified
2146 * constructor of the class or interface represented by this
2147 * {@code Class} object. The {@code parameterTypes} parameter is
2148 * an array of {@code Class} objects that identify the constructor's
2149 * formal parameter types, in declared order.
2150 *
2151 * If this {@code Class} object represents an inner class
2152 * declared in a non-static context, the formal parameter types
2153 * include the explicit enclosing instance as the first parameter.
2154 *
2155 * @param parameterTypes the parameter array
2156 * @return The {@code Constructor} object for the constructor with the
2157 * specified parameter list
2158 * @throws NoSuchMethodException if a matching method is not found.
2159 * @throws SecurityException
2160 * If a security manager, <i>s</i>, is present and any of the
2166 * class loader of this class and invocation of
2167 * {@link SecurityManager#checkPermission
2168 * s.checkPermission} method with
2169 * {@code RuntimePermission("accessDeclaredMembers")}
2170 * denies access to the declared constructor
2171 *
2172 * <li> the caller's class loader is not the same as or an
2173 * ancestor of the class loader for the current class and
2174 * invocation of {@link SecurityManager#checkPackageAccess
2175 * s.checkPackageAccess()} denies access to the package
2176 * of this class
2177 *
2178 * </ul>
2179 *
2180 * @since 1.1
2181 */
2182 @CallerSensitive
2183 public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
2184 throws NoSuchMethodException, SecurityException {
2185 checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
2186 return getConstructor0(parameterTypes, Member.DECLARED);
2187 }
2188
2189 /**
2190 * Finds a resource with a given name. The rules for searching resources
2191 * associated with a given class are implemented by the defining
2192 * {@linkplain ClassLoader class loader} of the class. This method
2193 * delegates to this object's class loader. If this object was loaded by
2194 * the bootstrap class loader, the method delegates to {@link
2195 * ClassLoader#getSystemResourceAsStream}.
2196 *
2197 * <p> Before delegation, an absolute resource name is constructed from the
2198 * given resource name using this algorithm:
2199 *
2200 * <ul>
2201 *
2202 * <li> If the {@code name} begins with a {@code '/'}
2203 * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
2204 * portion of the {@code name} following the {@code '/'}.
2205 *
2206 * <li> Otherwise, the absolute name is of the following form:
2606 checkInitted();
2607 Field[] res;
2608 ReflectionData<T> rd = reflectionData();
2609 if (rd != null) {
2610 res = rd.publicFields;
2611 if (res != null) return res;
2612 }
2613
2614 // No cached value available; compute value recursively.
2615 // Traverse in correct order for getField().
2616 List<Field> fields = new ArrayList<>();
2617 if (traversedInterfaces == null) {
2618 traversedInterfaces = new HashSet<>();
2619 }
2620
2621 // Local fields
2622 Field[] tmp = privateGetDeclaredFields(true);
2623 addAll(fields, tmp);
2624
2625 // Direct superinterfaces, recursively
2626 for (Class<?> c : getInterfaces()) {
2627 if (!traversedInterfaces.contains(c)) {
2628 traversedInterfaces.add(c);
2629 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2630 }
2631 }
2632
2633 // Direct superclass, recursively
2634 if (!isInterface()) {
2635 Class<?> c = getSuperclass();
2636 if (c != null) {
2637 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2638 }
2639 }
2640
2641 res = new Field[fields.size()];
2642 fields.toArray(res);
2643 if (rd != null) {
2644 rd.publicFields = res;
2645 }
2646 return res;
2700 private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2701 checkInitted();
2702 Method[] res;
2703 ReflectionData<T> rd = reflectionData();
2704 if (rd != null) {
2705 res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;
2706 if (res != null) return res;
2707 }
2708 // No cached value available; request value from VM
2709 res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2710 if (rd != null) {
2711 if (publicOnly) {
2712 rd.declaredPublicMethods = res;
2713 } else {
2714 rd.declaredMethods = res;
2715 }
2716 }
2717 return res;
2718 }
2719
2720 static class MethodArray {
2721 // Don't add or remove methods except by add() or remove() calls.
2722 private Method[] methods;
2723 private int length;
2724 private int defaults;
2725
2726 MethodArray() {
2727 this(20);
2728 }
2729
2730 MethodArray(int initialSize) {
2731 if (initialSize < 2)
2732 throw new IllegalArgumentException("Size should be 2 or more");
2733
2734 methods = new Method[initialSize];
2735 length = 0;
2736 defaults = 0;
2737 }
2738
2739 boolean hasDefaults() {
2740 return defaults != 0;
2741 }
2742
2743 void add(Method m) {
2744 if (length == methods.length) {
2745 methods = Arrays.copyOf(methods, 2 * methods.length);
2746 }
2747 methods[length++] = m;
2748
2749 if (m != null && m.isDefault())
2750 defaults++;
2751 }
2752
2753 void addAll(Method[] ma) {
2754 for (Method m : ma) {
2755 add(m);
2756 }
2757 }
2758
2759 void addAll(MethodArray ma) {
2760 for (int i = 0; i < ma.length(); i++) {
2761 add(ma.get(i));
2762 }
2763 }
2764
2765 void addIfNotPresent(Method newMethod) {
2766 for (int i = 0; i < length; i++) {
2767 Method m = methods[i];
2768 if (m == newMethod || (m != null && m.equals(newMethod))) {
2769 return;
2770 }
2771 }
2772 add(newMethod);
2773 }
2774
2775 void addAllIfNotPresent(MethodArray newMethods) {
2776 for (int i = 0; i < newMethods.length(); i++) {
2777 Method m = newMethods.get(i);
2778 if (m != null) {
2779 addIfNotPresent(m);
2780 }
2781 }
2782 }
2783
2784 /* Add Methods declared in an interface to this MethodArray.
2785 * Static methods declared in interfaces are not inherited.
2786 */
2787 void addInterfaceMethods(Method[] methods) {
2788 for (Method candidate : methods) {
2789 if (!Modifier.isStatic(candidate.getModifiers())) {
2790 add(candidate);
2791 }
2792 }
2793 }
2794
2795 int length() {
2796 return length;
2797 }
2798
2799 Method get(int i) {
2800 return methods[i];
2801 }
2802
2803 Method getFirst() {
2804 for (Method m : methods)
2805 if (m != null)
2806 return m;
2807 return null;
2808 }
2809
2810 void removeByNameAndDescriptor(Method toRemove) {
2811 for (int i = 0; i < length; i++) {
2812 Method m = methods[i];
2813 if (m != null && matchesNameAndDescriptor(m, toRemove)) {
2814 remove(i);
2815 }
2816 }
2817 }
2818
2819 private void remove(int i) {
2820 if (methods[i] != null && methods[i].isDefault())
2821 defaults--;
2822 methods[i] = null;
2823 }
2824
2825 private boolean matchesNameAndDescriptor(Method m1, Method m2) {
2826 return m1.getReturnType() == m2.getReturnType() &&
2827 m1.getName() == m2.getName() && // name is guaranteed to be interned
2828 arrayContentsEq(m1.getParameterTypes(),
2829 m2.getParameterTypes());
2830 }
2831
2832 void compactAndTrim() {
2833 int newPos = 0;
2834 // Get rid of null slots
2835 for (int pos = 0; pos < length; pos++) {
2836 Method m = methods[pos];
2837 if (m != null) {
2838 if (pos != newPos) {
2839 methods[newPos] = m;
2840 }
2841 newPos++;
2842 }
2843 }
2844 if (newPos != methods.length) {
2845 methods = Arrays.copyOf(methods, newPos);
2846 }
2847 }
2848
2849 /* Removes all Methods from this MethodArray that have a more specific
2850 * default Method in this MethodArray.
2851 *
2852 * Users of MethodArray are responsible for pruning Methods that have
2853 * a more specific <em>concrete</em> Method.
2854 */
2855 void removeLessSpecifics() {
2856 if (!hasDefaults())
2857 return;
2858
2859 for (int i = 0; i < length; i++) {
2860 Method m = get(i);
2861 if (m == null || !m.isDefault())
2862 continue;
2863
2864 for (int j = 0; j < length; j++) {
2865 if (i == j)
2866 continue;
2867
2868 Method candidate = get(j);
2869 if (candidate == null)
2870 continue;
2871
2872 if (!matchesNameAndDescriptor(m, candidate))
2873 continue;
2874
2875 if (hasMoreSpecificClass(m, candidate))
2876 remove(j);
2877 }
2878 }
2879 }
2880
2881 Method[] getArray() {
2882 return methods;
2883 }
2884
2885 // Returns true if m1 is more specific than m2
2886 static boolean hasMoreSpecificClass(Method m1, Method m2) {
2887 Class<?> m1Class = m1.getDeclaringClass();
2888 Class<?> m2Class = m2.getDeclaringClass();
2889 return m1Class != m2Class && m2Class.isAssignableFrom(m1Class);
2890 }
2891 }
2892
2893
2894 // Returns an array of "root" methods. These Method objects must NOT
2895 // be propagated to the outside world, but must instead be copied
2896 // via ReflectionFactory.copyMethod.
2897 private Method[] privateGetPublicMethods() {
2898 checkInitted();
2899 Method[] res;
2900 ReflectionData<T> rd = reflectionData();
2901 if (rd != null) {
2902 res = rd.publicMethods;
2903 if (res != null) return res;
2904 }
2905
2906 // No cached value available; compute value recursively.
2907 // Start by fetching public declared methods
2908 MethodArray methods = new MethodArray();
2909 {
2910 Method[] tmp = privateGetDeclaredMethods(true);
2911 methods.addAll(tmp);
2912 }
2913 // Now recur over superclass and direct superinterfaces.
2914 // Go over superinterfaces first so we can more easily filter
2915 // out concrete implementations inherited from superclasses at
2916 // the end.
2917 MethodArray inheritedMethods = new MethodArray();
2918 for (Class<?> i : getInterfaces()) {
2919 inheritedMethods.addInterfaceMethods(i.privateGetPublicMethods());
2920 }
2921 if (!isInterface()) {
2922 Class<?> c = getSuperclass();
2923 if (c != null) {
2924 MethodArray supers = new MethodArray();
2925 supers.addAll(c.privateGetPublicMethods());
2926 // Filter out concrete implementations of any
2927 // interface methods
2928 for (int i = 0; i < supers.length(); i++) {
2929 Method m = supers.get(i);
2930 if (m != null &&
2931 !Modifier.isAbstract(m.getModifiers()) &&
2932 !m.isDefault()) {
2933 inheritedMethods.removeByNameAndDescriptor(m);
2934 }
2935 }
2936 // Insert superclass's inherited methods before
2937 // superinterfaces' to satisfy getMethod's search
2938 // order
2939 supers.addAll(inheritedMethods);
2940 inheritedMethods = supers;
2941 }
2942 }
2943 // Filter out all local methods from inherited ones
2944 for (int i = 0; i < methods.length(); i++) {
2945 Method m = methods.get(i);
2946 inheritedMethods.removeByNameAndDescriptor(m);
2947 }
2948 methods.addAllIfNotPresent(inheritedMethods);
2949 methods.removeLessSpecifics();
2950 methods.compactAndTrim();
2951 res = methods.getArray();
2952 if (rd != null) {
2953 rd.publicMethods = res;
2954 }
2955 return res;
2956 }
2957
2958
2959 //
2960 // Helpers for fetchers of one field, method, or constructor
2961 //
2962
2963 private static Field searchFields(Field[] fields, String name) {
2964 String internedName = name.intern();
2965 for (Field field : fields) {
2966 if (field.getName() == internedName) {
2967 return getReflectionFactory().copyField(field);
2968 }
2969 }
2970 return null;
2971 }
2972
2973 private Field getField0(String name) throws NoSuchFieldException {
2974 // Note: the intent is that the search algorithm this routine
2975 // uses be equivalent to the ordering imposed by
2976 // privateGetPublicFields(). It fetches only the declared
2977 // public fields for each class, however, to reduce the number
2978 // of Field objects which have to be created for the common
2979 // case where the field being requested is declared in the
2980 // class which is being queried.
2981 Field res;
2982 // Search declared public fields
2983 if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
2984 return res;
2985 }
2986 // Direct superinterfaces, recursively
2987 Class<?>[] interfaces = getInterfaces();
2988 for (Class<?> c : interfaces) {
2989 if ((res = c.getField0(name)) != null) {
2990 return res;
2991 }
2992 }
2993 // Direct superclass, recursively
2994 if (!isInterface()) {
2995 Class<?> c = getSuperclass();
2996 if (c != null) {
2997 if ((res = c.getField0(name)) != null) {
2998 return res;
2999 }
3000 }
3001 }
3002 return null;
3003 }
3004
3005 private static Method searchMethods(Method[] methods,
3006 String name,
3007 Class<?>[] parameterTypes)
3008 {
3009 Method res = null;
3010 String internedName = name.intern();
3011 for (Method m : methods) {
3012 if (m.getName() == internedName
3013 && arrayContentsEq(parameterTypes, m.getParameterTypes())
3014 && (res == null
3015 || res.getReturnType().isAssignableFrom(m.getReturnType())))
3016 res = m;
3017 }
3018
3019 return (res == null ? res : getReflectionFactory().copyMethod(res));
3020 }
3021
3022 private Method getMethod0(String name, Class<?>[] parameterTypes, boolean includeStaticMethods) {
3023 MethodArray interfaceCandidates = new MethodArray(2);
3024 Method res = privateGetMethodRecursive(name, parameterTypes, includeStaticMethods, interfaceCandidates);
3025 if (res != null)
3026 return res;
3027
3028 // Not found on class or superclass directly
3029 interfaceCandidates.removeLessSpecifics();
3030 return interfaceCandidates.getFirst(); // may be null
3031 }
3032
3033 private Method privateGetMethodRecursive(String name,
3034 Class<?>[] parameterTypes,
3035 boolean includeStaticMethods,
3036 MethodArray allInterfaceCandidates) {
3037 // Note: the intent is that the search algorithm this routine
3038 // uses be equivalent to the ordering imposed by
3039 // privateGetPublicMethods(). It fetches only the declared
3040 // public methods for each class, however, to reduce the
3041 // number of Method objects which have to be created for the
3042 // common case where the method being requested is declared in
3043 // the class which is being queried.
3044 //
3045 // Due to default methods, unless a method is found on a superclass,
3046 // methods declared in any superinterface needs to be considered.
3047 // Collect all candidates declared in superinterfaces in {@code
3048 // allInterfaceCandidates} and select the most specific if no match on
3049 // a superclass is found.
3050
3051 // Must _not_ return root methods
3052 Method res;
3053 // Search declared public methods
3054 if ((res = searchMethods(privateGetDeclaredMethods(true),
3055 name,
3056 parameterTypes)) != null) {
3057 if (includeStaticMethods || !Modifier.isStatic(res.getModifiers()))
3058 return res;
3059 }
3060 // Search superclass's methods
3061 if (!isInterface()) {
3062 Class<? super T> c = getSuperclass();
3063 if (c != null) {
3064 if ((res = c.getMethod0(name, parameterTypes, true)) != null) {
3065 return res;
3066 }
3067 }
3068 }
3069 // Search superinterfaces' methods
3070 Class<?>[] interfaces = getInterfaces();
3071 for (Class<?> c : interfaces)
3072 if ((res = c.getMethod0(name, parameterTypes, false)) != null)
3073 allInterfaceCandidates.add(res);
3074 // Not found
3075 return null;
3076 }
3077
3078 private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
3079 int which) throws NoSuchMethodException
3080 {
3081 Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
3082 for (Constructor<T> constructor : constructors) {
3083 if (arrayContentsEq(parameterTypes,
3084 constructor.getParameterTypes())) {
3085 return getReflectionFactory().copyConstructor(constructor);
3086 }
3087 }
3088 throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
3089 }
3090
3091 //
3092 // Other helpers and base implementation
3093 //
3094
3095 private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
3096 if (a1 == null) {
3097 return a2 == null || a2.length == 0;
3098 }
3099
3100 if (a2 == null) {
3101 return a1.length == 0;
3102 }
3103
3104 if (a1.length != a2.length) {
3105 return false;
|
28 import java.lang.reflect.AnnotatedElement;
29 import java.lang.reflect.Array;
30 import java.lang.reflect.GenericArrayType;
31 import java.lang.reflect.GenericDeclaration;
32 import java.lang.reflect.Member;
33 import java.lang.reflect.Field;
34 import java.lang.reflect.Executable;
35 import java.lang.reflect.Method;
36 import java.lang.reflect.Constructor;
37 import java.lang.reflect.Modifier;
38 import java.lang.reflect.Type;
39 import java.lang.reflect.TypeVariable;
40 import java.lang.reflect.InvocationTargetException;
41 import java.lang.reflect.AnnotatedType;
42 import java.lang.ref.SoftReference;
43 import java.io.InputStream;
44 import java.io.ObjectStreamField;
45 import java.security.AccessController;
46 import java.security.PrivilegedAction;
47 import java.util.ArrayList;
48 import java.util.Collection;
49 import java.util.HashSet;
50 import java.util.LinkedHashMap;
51 import java.util.List;
52 import java.util.Set;
53 import java.util.Map;
54 import java.util.HashMap;
55 import java.util.Objects;
56 import java.util.StringJoiner;
57 import sun.misc.Unsafe;
58 import sun.reflect.CallerSensitive;
59 import sun.reflect.ConstantPool;
60 import sun.reflect.Reflection;
61 import sun.reflect.ReflectionFactory;
62 import sun.reflect.generics.factory.CoreReflectionFactory;
63 import sun.reflect.generics.factory.GenericsFactory;
64 import sun.reflect.generics.repository.ClassRepository;
65 import sun.reflect.generics.repository.MethodRepository;
66 import sun.reflect.generics.repository.ConstructorRepository;
67 import sun.reflect.generics.scope.ClassScope;
393 @CallerSensitive
394 public T newInstance()
395 throws InstantiationException, IllegalAccessException
396 {
397 if (System.getSecurityManager() != null) {
398 checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
399 }
400
401 // NOTE: the following code may not be strictly correct under
402 // the current Java memory model.
403
404 // Constructor lookup
405 if (cachedConstructor == null) {
406 if (this == Class.class) {
407 throw new IllegalAccessException(
408 "Can not call newInstance() on the Class for java.lang.Class"
409 );
410 }
411 try {
412 Class<?>[] empty = {};
413 // must copy constructor since we are modifying it
414 final Constructor<T> c = getReflectionFactory().copyConstructor(
415 getConstructor0(empty, Member.DECLARED));
416 // Disable accessibility checks on the constructor
417 // since we have to do the security check here anyway
418 // (the stack depth is wrong for the Constructor's
419 // security check to work)
420 java.security.AccessController.doPrivileged(
421 new java.security.PrivilegedAction<Void>() {
422 public Void run() {
423 c.setAccessible(true);
424 return null;
425 }
426 });
427 cachedConstructor = c;
428 } catch (NoSuchMethodException e) {
429 throw (InstantiationException)
430 new InstantiationException(getName()).initCause(e);
431 }
432 }
433 Constructor<T> tmpConstructor = cachedConstructor;
434 // Security check (same as in java.lang.reflect.Constructor)
435 int modifiers = tmpConstructor.getModifiers();
826 *
827 * <p>If this object represents an interface, the array contains objects
828 * representing all interfaces directly extended by the interface. The
829 * order of the interface objects in the array corresponds to the order of
830 * the interface names in the {@code extends} clause of the declaration of
831 * the interface represented by this object.
832 *
833 * <p>If this object represents a class or interface that implements no
834 * interfaces, the method returns an array of length 0.
835 *
836 * <p>If this object represents a primitive type or void, the method
837 * returns an array of length 0.
838 *
839 * <p>If this {@code Class} object represents an array type, the
840 * interfaces {@code Cloneable} and {@code java.io.Serializable} are
841 * returned in that order.
842 *
843 * @return an array of interfaces directly implemented by this class
844 */
845 public Class<?>[] getInterfaces() {
846 return getInterfaces(true);
847 }
848
849 private Class<?>[] getInterfaces(boolean cloneArray) {
850 ReflectionData<T> rd = reflectionData();
851 if (rd == null) {
852 // no cloning required
853 return getInterfaces0();
854 } else {
855 Class<?>[] interfaces = rd.interfaces;
856 if (interfaces == null) {
857 interfaces = getInterfaces0();
858 rd.interfaces = interfaces;
859 }
860 // defensively copy cached array before handing over to user code
861 return cloneArray ? interfaces.clone() : interfaces;
862 }
863 }
864
865 private native Class<?>[] getInterfaces0();
866
867 /**
868 * Returns the {@code Type}s representing the interfaces
869 * directly implemented by the class or interface represented by
870 * this object.
871 *
872 * <p>If a superinterface is a parameterized type, the
873 * {@code Type} object returned for it must accurately reflect
874 * the actual type parameters used in the source code. The
875 * parameterized type representing each superinterface is created
876 * if it had not been created before. See the declaration of
877 * {@link java.lang.reflect.ParameterizedType ParameterizedType}
878 * for the semantics of the creation process for parameterized
879 * types.
880 *
881 * <p>If this object represents a class, the return value is an array
1698 * @throws SecurityException
1699 * If a security manager, <i>s</i>, is present and
1700 * the caller's class loader is not the same as or an
1701 * ancestor of the class loader for the current class and
1702 * invocation of {@link SecurityManager#checkPackageAccess
1703 * s.checkPackageAccess()} denies access to the package
1704 * of this class.
1705 *
1706 * @since 1.1
1707 * @jls 8.2 Class Members
1708 * @jls 8.3 Field Declarations
1709 */
1710 @CallerSensitive
1711 public Field getField(String name)
1712 throws NoSuchFieldException, SecurityException {
1713 checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
1714 Field field = getField0(name);
1715 if (field == null) {
1716 throw new NoSuchFieldException(name);
1717 }
1718 return getReflectionFactory().copyField(field);
1719 }
1720
1721
1722 /**
1723 * Returns a {@code Method} object that reflects the specified public
1724 * member method of the class or interface represented by this
1725 * {@code Class} object. The {@code name} parameter is a
1726 * {@code String} specifying the simple name of the desired method. The
1727 * {@code parameterTypes} parameter is an array of {@code Class}
1728 * objects that identify the method's formal parameter types, in declared
1729 * order. If {@code parameterTypes} is {@code null}, it is
1730 * treated as if it were an empty array.
1731 *
1732 * <p> If the {@code name} is "{@code <init>}" or "{@code <clinit>}" a
1733 * {@code NoSuchMethodException} is raised. Otherwise, the method to
1734 * be reflected is determined by the algorithm that follows. Let C be the
1735 * class or interface represented by this object:
1736 * <OL>
1737 * <LI> C is searched for a <I>matching method</I>, as defined below. If a
1738 * matching method is found, it is reflected.</LI>
1781 * @throws SecurityException
1782 * If a security manager, <i>s</i>, is present and
1783 * the caller's class loader is not the same as or an
1784 * ancestor of the class loader for the current class and
1785 * invocation of {@link SecurityManager#checkPackageAccess
1786 * s.checkPackageAccess()} denies access to the package
1787 * of this class.
1788 *
1789 * @jls 8.2 Class Members
1790 * @jls 8.4 Method Declarations
1791 * @since 1.1
1792 */
1793 @CallerSensitive
1794 public Method getMethod(String name, Class<?>... parameterTypes)
1795 throws NoSuchMethodException, SecurityException {
1796 checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
1797 Method method = getMethod0(name, parameterTypes, true);
1798 if (method == null) {
1799 throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
1800 }
1801 return getReflectionFactory().copyMethod(method);
1802 }
1803
1804
1805 /**
1806 * Returns a {@code Constructor} object that reflects the specified
1807 * public constructor of the class represented by this {@code Class}
1808 * object. The {@code parameterTypes} parameter is an array of
1809 * {@code Class} objects that identify the constructor's formal
1810 * parameter types, in declared order.
1811 *
1812 * If this {@code Class} object represents an inner class
1813 * declared in a non-static context, the formal parameter types
1814 * include the explicit enclosing instance as the first parameter.
1815 *
1816 * <p> The constructor to reflect is the public constructor of the class
1817 * represented by this {@code Class} object whose formal parameter
1818 * types match those specified by {@code parameterTypes}.
1819 *
1820 * @param parameterTypes the parameter array
1821 * @return the {@code Constructor} object of the public constructor that
1822 * matches the specified {@code parameterTypes}
1823 * @throws NoSuchMethodException if a matching method is not found.
1824 * @throws SecurityException
1825 * If a security manager, <i>s</i>, is present and
1826 * the caller's class loader is not the same as or an
1827 * ancestor of the class loader for the current class and
1828 * invocation of {@link SecurityManager#checkPackageAccess
1829 * s.checkPackageAccess()} denies access to the package
1830 * of this class.
1831 *
1832 * @since 1.1
1833 */
1834 @CallerSensitive
1835 public Constructor<T> getConstructor(Class<?>... parameterTypes)
1836 throws NoSuchMethodException, SecurityException {
1837 checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
1838 return getReflectionFactory().copyConstructor(
1839 getConstructor0(parameterTypes, Member.PUBLIC));
1840 }
1841
1842
1843 /**
1844 * Returns an array of {@code Class} objects reflecting all the
1845 * classes and interfaces declared as members of the class represented by
1846 * this {@code Class} object. This includes public, protected, default
1847 * (package) access, and private classes and interfaces declared by the
1848 * class, but excludes inherited classes and interfaces. This method
1849 * returns an array of length 0 if the class declares no classes or
1850 * interfaces as members, or if this {@code Class} object represents a
1851 * primitive type, an array class, or void.
1852 *
1853 * @return the array of {@code Class} objects representing all the
1854 * declared members of this class
1855 * @throws SecurityException
1856 * If a security manager, <i>s</i>, is present and any of the
1857 * following conditions is met:
1858 *
1859 * <ul>
2066 * <li> the caller's class loader is not the same as or an
2067 * ancestor of the class loader for the current class and
2068 * invocation of {@link SecurityManager#checkPackageAccess
2069 * s.checkPackageAccess()} denies access to the package
2070 * of this class
2071 *
2072 * </ul>
2073 *
2074 * @since 1.1
2075 * @jls 8.2 Class Members
2076 * @jls 8.3 Field Declarations
2077 */
2078 @CallerSensitive
2079 public Field getDeclaredField(String name)
2080 throws NoSuchFieldException, SecurityException {
2081 checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
2082 Field field = searchFields(privateGetDeclaredFields(false), name);
2083 if (field == null) {
2084 throw new NoSuchFieldException(name);
2085 }
2086 return getReflectionFactory().copyField(field);
2087 }
2088
2089
2090 /**
2091 * Returns a {@code Method} object that reflects the specified
2092 * declared method of the class or interface represented by this
2093 * {@code Class} object. The {@code name} parameter is a
2094 * {@code String} that specifies the simple name of the desired
2095 * method, and the {@code parameterTypes} parameter is an array of
2096 * {@code Class} objects that identify the method's formal parameter
2097 * types, in declared order. If more than one method with the same
2098 * parameter types is declared in a class, and one of these methods has a
2099 * return type that is more specific than any of the others, that method is
2100 * returned; otherwise one of the methods is chosen arbitrarily. If the
2101 * name is "<init>"or "<clinit>" a {@code NoSuchMethodException}
2102 * is raised.
2103 *
2104 * <p> If this {@code Class} object represents an array type, then this
2105 * method does not find the {@code clone()} method.
2106 *
2126 * <li> the caller's class loader is not the same as or an
2127 * ancestor of the class loader for the current class and
2128 * invocation of {@link SecurityManager#checkPackageAccess
2129 * s.checkPackageAccess()} denies access to the package
2130 * of this class
2131 *
2132 * </ul>
2133 *
2134 * @jls 8.2 Class Members
2135 * @jls 8.4 Method Declarations
2136 * @since 1.1
2137 */
2138 @CallerSensitive
2139 public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
2140 throws NoSuchMethodException, SecurityException {
2141 checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
2142 Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
2143 if (method == null) {
2144 throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
2145 }
2146 return getReflectionFactory().copyMethod(method);
2147 }
2148
2149
2150 /**
2151 * Returns a {@code Constructor} object that reflects the specified
2152 * constructor of the class or interface represented by this
2153 * {@code Class} object. The {@code parameterTypes} parameter is
2154 * an array of {@code Class} objects that identify the constructor's
2155 * formal parameter types, in declared order.
2156 *
2157 * If this {@code Class} object represents an inner class
2158 * declared in a non-static context, the formal parameter types
2159 * include the explicit enclosing instance as the first parameter.
2160 *
2161 * @param parameterTypes the parameter array
2162 * @return The {@code Constructor} object for the constructor with the
2163 * specified parameter list
2164 * @throws NoSuchMethodException if a matching method is not found.
2165 * @throws SecurityException
2166 * If a security manager, <i>s</i>, is present and any of the
2172 * class loader of this class and invocation of
2173 * {@link SecurityManager#checkPermission
2174 * s.checkPermission} method with
2175 * {@code RuntimePermission("accessDeclaredMembers")}
2176 * denies access to the declared constructor
2177 *
2178 * <li> the caller's class loader is not the same as or an
2179 * ancestor of the class loader for the current class and
2180 * invocation of {@link SecurityManager#checkPackageAccess
2181 * s.checkPackageAccess()} denies access to the package
2182 * of this class
2183 *
2184 * </ul>
2185 *
2186 * @since 1.1
2187 */
2188 @CallerSensitive
2189 public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
2190 throws NoSuchMethodException, SecurityException {
2191 checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
2192 return getReflectionFactory().copyConstructor(
2193 getConstructor0(parameterTypes, Member.DECLARED));
2194 }
2195
2196 /**
2197 * Finds a resource with a given name. The rules for searching resources
2198 * associated with a given class are implemented by the defining
2199 * {@linkplain ClassLoader class loader} of the class. This method
2200 * delegates to this object's class loader. If this object was loaded by
2201 * the bootstrap class loader, the method delegates to {@link
2202 * ClassLoader#getSystemResourceAsStream}.
2203 *
2204 * <p> Before delegation, an absolute resource name is constructed from the
2205 * given resource name using this algorithm:
2206 *
2207 * <ul>
2208 *
2209 * <li> If the {@code name} begins with a {@code '/'}
2210 * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
2211 * portion of the {@code name} following the {@code '/'}.
2212 *
2213 * <li> Otherwise, the absolute name is of the following form:
2613 checkInitted();
2614 Field[] res;
2615 ReflectionData<T> rd = reflectionData();
2616 if (rd != null) {
2617 res = rd.publicFields;
2618 if (res != null) return res;
2619 }
2620
2621 // No cached value available; compute value recursively.
2622 // Traverse in correct order for getField().
2623 List<Field> fields = new ArrayList<>();
2624 if (traversedInterfaces == null) {
2625 traversedInterfaces = new HashSet<>();
2626 }
2627
2628 // Local fields
2629 Field[] tmp = privateGetDeclaredFields(true);
2630 addAll(fields, tmp);
2631
2632 // Direct superinterfaces, recursively
2633 for (Class<?> c : getInterfaces(false)) {
2634 if (!traversedInterfaces.contains(c)) {
2635 traversedInterfaces.add(c);
2636 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2637 }
2638 }
2639
2640 // Direct superclass, recursively
2641 if (!isInterface()) {
2642 Class<?> c = getSuperclass();
2643 if (c != null) {
2644 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2645 }
2646 }
2647
2648 res = new Field[fields.size()];
2649 fields.toArray(res);
2650 if (rd != null) {
2651 rd.publicFields = res;
2652 }
2653 return res;
2707 private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2708 checkInitted();
2709 Method[] res;
2710 ReflectionData<T> rd = reflectionData();
2711 if (rd != null) {
2712 res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;
2713 if (res != null) return res;
2714 }
2715 // No cached value available; request value from VM
2716 res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2717 if (rd != null) {
2718 if (publicOnly) {
2719 rd.declaredPublicMethods = res;
2720 } else {
2721 rd.declaredMethods = res;
2722 }
2723 }
2724 return res;
2725 }
2726
2727 private static final Method[] EMPTY_METHODS = new Method[0];
2728
2729 // Returns an array of "root" methods. These Method objects must NOT
2730 // be propagated to the outside world, but must instead be copied
2731 // via ReflectionFactory.copyMethod.
2732 private Method[] privateGetPublicMethods() {
2733 checkInitted();
2734 Method[] res;
2735 ReflectionData<T> rd = reflectionData();
2736 if (rd != null) {
2737 res = rd.publicMethods;
2738 if (res != null) return res;
2739 }
2740
2741 Method[] declaredMethods = privateGetDeclaredMethods(true);
2742 Class<?> superclass = getSuperclass();
2743 Class<?>[] interfaces = getInterfaces(false);
2744
2745 // optimization:
2746 // if we don't have a superclass (either we are j.l.Object or an interface)
2747 // and don't have (super)interfaces either, then public methods consist
2748 // of declared public methods
2749 if (superclass == null && interfaces.length == 0) {
2750 res = declaredMethods;
2751 } else {
2752 // we have to do some logic
2753 Method[] superclassMethods = (superclass == null)
2754 ? EMPTY_METHODS
2755 : superclass.privateGetPublicMethods();
2756 Method[][] interfacesMethods = new Method[interfaces.length][];
2757 int interfacesMethodsCount = 0;
2758 for (int i = 0; i < interfaces.length; i++) {
2759 interfacesMethods[i] = interfaces[i].privateGetPublicMethods();
2760 interfacesMethodsCount += interfacesMethods[i].length;
2761 }
2762
2763 // ensure enough working capacity
2764 // (MethodTable implementation may not support dynamic resizing)
2765 MethodTable methodTable = MethodTable.newInstance(
2766 declaredMethods.length +
2767 superclassMethods.length +
2768 interfacesMethodsCount
2769 );
2770
2771 // declared methods first
2772 for (Method m : declaredMethods) {
2773 methodTable.add(m);
2774 }
2775
2776 // inherited methods from superclass
2777 for (Method m : superclassMethods) {
2778 methodTable.addUnlessDeclaredExists(m, this);
2779 }
2780
2781 // inherited methods from (super)interfaces
2782 for (Method[] ms : interfacesMethods) {
2783 for (Method m : ms) {
2784 // interface static methods are not inherited
2785 if (!Modifier.isStatic(m.getModifiers())) {
2786 methodTable.consolidate(m, this);
2787 }
2788 }
2789 }
2790
2791 res = methodTable.getMethods();
2792 }
2793
2794 if (rd != null) {
2795 rd.publicMethods = res;
2796 }
2797 return res;
2798 }
2799
2800
2801 //
2802 // Helpers for fetchers of one field, method, or constructor
2803 //
2804
2805 /**
2806 * This method does not copy returned 'root' Field object. It MUST be copied
2807 * with ReflectionFactory before handed to any code outside java.lang.Class
2808 * or modified.
2809 */
2810 private static Field searchFields(Field[] fields, String name) {
2811 String internedName = name.intern();
2812 for (Field field : fields) {
2813 if (field.getName() == internedName) {
2814 return field;
2815 }
2816 }
2817 return null;
2818 }
2819
2820 /**
2821 * This method returns 'root' Field object. It MUST be copied with ReflectionFactory
2822 * before handed to any code outside java.lang.Class or modified.
2823 */
2824 private Field getField0(String name) throws NoSuchFieldException {
2825 // Note: the intent is that the search algorithm this routine
2826 // uses be equivalent to the ordering imposed by
2827 // privateGetPublicFields(). It fetches only the declared
2828 // public fields for each class, however, to reduce the number
2829 // of Field objects which have to be created for the common
2830 // case where the field being requested is declared in the
2831 // class which is being queried.
2832 Field res;
2833 // Search declared public fields
2834 if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
2835 return res;
2836 }
2837 // Direct superinterfaces, recursively
2838 Class<?>[] interfaces = getInterfaces(false);
2839 for (Class<?> c : interfaces) {
2840 if ((res = c.getField0(name)) != null) {
2841 return res;
2842 }
2843 }
2844 // Direct superclass, recursively
2845 if (!isInterface()) {
2846 Class<?> c = getSuperclass();
2847 if (c != null) {
2848 if ((res = c.getField0(name)) != null) {
2849 return res;
2850 }
2851 }
2852 }
2853 return null;
2854 }
2855
2856 /**
2857 * This method does not copy returned 'root' Method object. It MUST be copied
2858 * with ReflectionFactory before handed to any code outside java.lang.Class
2859 * or modified.
2860 */
2861 private static Method searchMethods(Method[] methods,
2862 String name,
2863 Class<?>[] parameterTypes)
2864 {
2865 Method res = null;
2866 String internedName = name.intern();
2867 for (Method m : methods) {
2868 if (m.getName() == internedName
2869 && arrayContentsEq(parameterTypes, m.getParameterTypes())
2870 && (res == null
2871 || res.getReturnType().isAssignableFrom(m.getReturnType())))
2872 res = m;
2873 }
2874
2875 return res;
2876 }
2877
2878 /**
2879 * This method returns 'root' Method object. It MUST be copied with ReflectionFactory
2880 * before handed to any code outside java.lang.Class or modified.
2881 */
2882 private Method getMethod0(String name, Class<?>[] parameterTypes, boolean includeStaticMethods) {
2883 // Note: the intent is that the search algorithm this routine
2884 // uses be equivalent to the ordering imposed by
2885 // privateGetPublicMethods(). It fetches only the declared
2886 // public methods for each class, however, to reduce the
2887 // number of Method objects which have to be created for the
2888 // common case where the method being requested is declared in
2889 // the class which is being queried.
2890 Method res;
2891 // 1st search declared public methods
2892 if ((res = searchMethods(privateGetDeclaredMethods(true),
2893 name,
2894 parameterTypes)) != null &&
2895 (includeStaticMethods ||
2896 !Modifier.isStatic(res.getModifiers()))) {
2897 return res;
2898 }
2899
2900 // 2nd we try the superclass.
2901 Class<? super T> superclass = getSuperclass();
2902 if (superclass != null &&
2903 (res = superclass.getMethod0(name, parameterTypes, includeStaticMethods)) != null) {
2904 return res;
2905 }
2906
2907 // last we check (super) interfaces
2908 Class<?>[] interfaces = getInterfaces(false);
2909 if (interfaces.length == 0) {
2910 return null;
2911 }
2912 // have to construct a MethodTable to consolidate
2913 // public methods from (super)interfaces
2914 MethodTable methodTable = MethodTable.newInstance(interfaces.length);
2915 for (Class<?> c : interfaces) {
2916 if ((res = c.getMethod0(name, parameterTypes, false)) != null) {
2917 methodTable.consolidate(res, this);
2918 }
2919 }
2920
2921 // return the first method with the most specific return type
2922 return methodTable.getFirstMethodWithMostSpecificReturnType();
2923 }
2924
2925 /**
2926 * This method returns 'root' Constructor object. It MUST be copied with ReflectionFactory
2927 * before handed to any code outside java.lang.Class or modified.
2928 */
2929 private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
2930 int which) throws NoSuchMethodException
2931 {
2932 Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
2933 for (Constructor<T> constructor : constructors) {
2934 if (arrayContentsEq(parameterTypes,
2935 constructor.getParameterTypes())) {
2936 return constructor;
2937 }
2938 }
2939 throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
2940 }
2941
2942 //
2943 // Other helpers and base implementation
2944 //
2945
2946 private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
2947 if (a1 == null) {
2948 return a2 == null || a2.length == 0;
2949 }
2950
2951 if (a2 == null) {
2952 return a1.length == 0;
2953 }
2954
2955 if (a1.length != a2.length) {
2956 return false;
|