257 }
258 return Lookup.newLookup(targetClass, newPreviousClass, newModes);
259 }
260
261 /**
262 * Performs an unchecked "crack" of a
263 * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
264 * The result is as if the user had obtained a lookup object capable enough
265 * to crack the target method handle, called
266 * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
267 * on the target to obtain its symbolic reference, and then called
268 * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
269 * to resolve the symbolic reference to a member.
270 * <p>
271 * If there is a security manager, its {@code checkPermission} method
272 * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
273 * @param <T> the desired type of the result, either {@link Member} or a subtype
274 * @param target a direct method handle to crack into symbolic reference components
275 * @param expected a class object representing the desired result type {@code T}
276 * @return a reference to the method, constructor, or field object
277 * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
278 * @exception NullPointerException if either argument is {@code null}
279 * @exception IllegalArgumentException if the target is not a direct method handle
280 * @exception ClassCastException if the member is not of the expected type
281 * @since 1.8
282 */
283 public static <T extends Member> T
284 reflectAs(Class<T> expected, MethodHandle target) {
285 SecurityManager smgr = System.getSecurityManager();
286 if (smgr != null) smgr.checkPermission(ACCESS_PERMISSION);
287 Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup
288 return lookup.revealDirect(target).reflectAs(expected, lookup);
289 }
290 // Copied from AccessibleObject, as used by Method.setAccessible, etc.:
291 private static final java.security.Permission ACCESS_PERMISSION =
292 new ReflectPermission("suppressAccessChecks");
293
294 /**
295 * A <em>lookup object</em> is a factory for creating method handles,
296 * when the creation requires access checking.
297 * Method handles do not perform
298 * access checks when they are called, but rather when they are created.
299 * Therefore, method handle access
300 * restrictions must be enforced when a method handle is created.
1737 * If the returned method handle is invoked, the method's class will
1738 * be initialized, if it has not already been initialized.
1739 * <p><b>Example:</b>
1740 * <blockquote><pre>{@code
1741 import static java.lang.invoke.MethodHandles.*;
1742 import static java.lang.invoke.MethodType.*;
1743 ...
1744 MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
1745 "asList", methodType(List.class, Object[].class));
1746 assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
1747 * }</pre></blockquote>
1748 * @param refc the class from which the method is accessed
1749 * @param name the name of the method
1750 * @param type the type of the method
1751 * @return the desired method handle
1752 * @throws NoSuchMethodException if the method does not exist
1753 * @throws IllegalAccessException if access checking fails,
1754 * or if the method is not {@code static},
1755 * or if the method's variable arity modifier bit
1756 * is set and {@code asVarargsCollector} fails
1757 * @exception SecurityException if a security manager is present and it
1758 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1759 * @throws NullPointerException if any argument is null
1760 */
1761 public
1762 MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1763 MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
1764 return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerClass(method));
1765 }
1766
1767 /**
1768 * Produces a method handle for a virtual method.
1769 * The type of the method handle will be that of the method,
1770 * with the receiver type (usually {@code refc}) prepended.
1771 * The method and all its argument types must be accessible to the lookup object.
1772 * <p>
1773 * When called, the handle will treat the first argument as a receiver
1774 * and, for non-private methods, dispatch on the receiver's type to determine which method
1775 * implementation to enter.
1776 * For private methods the named method in {@code refc} will be invoked on the receiver.
1777 * (The dispatching action is identical with that performed by an
1822 assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
1823 // constructor "internal method" must be accessed differently:
1824 MethodType MT_newString = methodType(void.class); //()V for new String()
1825 try { assertEquals("impossible", lookup()
1826 .findVirtual(String.class, "<init>", MT_newString));
1827 } catch (NoSuchMethodException ex) { } // OK
1828 MethodHandle MH_newString = publicLookup()
1829 .findConstructor(String.class, MT_newString);
1830 assertEquals("", (String) MH_newString.invokeExact());
1831 * }</pre></blockquote>
1832 *
1833 * @param refc the class or interface from which the method is accessed
1834 * @param name the name of the method
1835 * @param type the type of the method, with the receiver argument omitted
1836 * @return the desired method handle
1837 * @throws NoSuchMethodException if the method does not exist
1838 * @throws IllegalAccessException if access checking fails,
1839 * or if the method is {@code static},
1840 * or if the method's variable arity modifier bit
1841 * is set and {@code asVarargsCollector} fails
1842 * @exception SecurityException if a security manager is present and it
1843 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1844 * @throws NullPointerException if any argument is null
1845 */
1846 public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1847 if (refc == MethodHandle.class) {
1848 MethodHandle mh = findVirtualForMH(name, type);
1849 if (mh != null) return mh;
1850 } else if (refc == VarHandle.class) {
1851 MethodHandle mh = findVirtualForVH(name, type);
1852 if (mh != null) return mh;
1853 }
1854 byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
1855 MemberName method = resolveOrFail(refKind, refc, name, type);
1856 return getDirectMethod(refKind, refc, method, findBoundCallerClass(method));
1857 }
1858 private MethodHandle findVirtualForMH(String name, MethodType type) {
1859 // these names require special lookups because of the implicit MethodType argument
1860 if ("invoke".equals(name))
1861 return invoker(type);
1862 if ("invokeExact".equals(name))
1896 MethodHandle MH_newArrayList = publicLookup().findConstructor(
1897 ArrayList.class, methodType(void.class, Collection.class));
1898 Collection orig = Arrays.asList("x", "y");
1899 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
1900 assert(orig != copy);
1901 assertEquals(orig, copy);
1902 // a variable-arity constructor:
1903 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
1904 ProcessBuilder.class, methodType(void.class, String[].class));
1905 ProcessBuilder pb = (ProcessBuilder)
1906 MH_newProcessBuilder.invoke("x", "y", "z");
1907 assertEquals("[x, y, z]", pb.command().toString());
1908 * }</pre></blockquote>
1909 * @param refc the class or interface from which the method is accessed
1910 * @param type the type of the method, with the receiver argument omitted, and a void return type
1911 * @return the desired method handle
1912 * @throws NoSuchMethodException if the constructor does not exist
1913 * @throws IllegalAccessException if access checking fails
1914 * or if the method's variable arity modifier bit
1915 * is set and {@code asVarargsCollector} fails
1916 * @exception SecurityException if a security manager is present and it
1917 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1918 * @throws NullPointerException if any argument is null
1919 */
1920 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1921 if (refc.isArray()) {
1922 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
1923 }
1924 String name = "<init>";
1925 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
1926 return getDirectConstructor(refc, ctor);
1927 }
1928
1929 /**
1930 * Looks up a class by name from the lookup context defined by this {@code Lookup} object.
1931 * This method attempts to locate, load, and link the class, and then determines whether
1932 * the class is accessible to this {@code Lookup} object. The static
1933 * initializer of the class is not run.
1934 * <p>
1935 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
1936 * loader, and the {@linkplain #lookupModes() lookup modes}.
1937 * <p>
1938 * Note that this method throws errors related to loading and linking as
1939 * specified in Sections 12.2 and 12.3 of <em>The Java Language
1940 * Specification</em>.
1941 *
1942 * @param targetName the fully qualified name of the class to be looked up.
1943 * @return the requested class.
1944 * @exception SecurityException if a security manager is present and it
1945 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1946 * @throws LinkageError if the linkage fails
1947 * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
1948 * @throws IllegalAccessException if the class is not accessible, using the allowed access
1949 * modes.
1950 * @exception SecurityException if a security manager is present and it
1951 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1952 *
1953 * @jls 12.2 Loading of Classes and Interfaces
1954 * @jls 12.3 Linking of Classes and Interfaces
1955 * @since 9
1956 */
1957 public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {
1958 Class<?> targetClass = Class.forName(targetName, false, lookupClass.getClassLoader());
1959 return accessClass(targetClass);
1960 }
1961
1962 /**
1963 * Determines if a class can be accessed from the lookup context defined by
1964 * this {@code Lookup} object. The static initializer of the class is not run.
1965 * <p>
1966 * If the {@code targetClass} is in the same module as the lookup class,
1967 * the lookup class is {@code LC} in module {@code M1} and
1968 * the previous lookup class is in module {@code M0} or
1969 * {@code null} if not present,
1970 * {@code targetClass} is accessible if and only if one of the following is true:
2005 * containing the previous lookup class, then {@code targetClass} is accessible
2006 * if and only if one of the following is true:
2007 * <ul>
2008 * <li>{@code targetClass} is in {@code M0} and {@code M1}
2009 * {@linkplain Module#reads reads} {@code M0} and the type is
2010 * in a package that is exported to at least {@code M1}.
2011 * <li>{@code targetClass} is in {@code M1} and {@code M0}
2012 * {@linkplain Module#reads reads} {@code M1} and the type is
2013 * in a package that is exported to at least {@code M0}.
2014 * <li>{@code targetClass} is in a third module {@code M2} and both {@code M0}
2015 * and {@code M1} reads {@code M2} and the type is in a package
2016 * that is exported to at least both {@code M0} and {@code M2}.
2017 * </ul>
2018 * <p>
2019 * Otherwise, {@code targetClass} is not accessible.
2020 *
2021 * @param targetClass the class to be access-checked
2022 * @return the class that has been access-checked
2023 * @throws IllegalAccessException if the class is not accessible from the lookup class
2024 * and previous lookup class, if present, using the allowed access modes.
2025 * @exception SecurityException if a security manager is present and it
2026 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2027 * @since 9
2028 * @see <a href="#cross-module-lookup">Cross-module lookups</a>
2029 */
2030 public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException {
2031 if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) {
2032 throw new MemberName(targetClass).makeAccessException("access violation", this);
2033 }
2034 checkSecurityManager(targetClass, null);
2035 return targetClass;
2036 }
2037
2038 /**
2039 * Produces an early-bound method handle for a virtual method.
2040 * It will bypass checks for overriding methods on the receiver,
2041 * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
2042 * instruction from within the explicitly specified {@code specialCaller}.
2043 * The type of the method handle will be that of the method,
2044 * with a suitably restricted receiver type prepended.
2045 * (The receiver type will be {@code specialCaller} or a subtype.)
2087 assertEquals("[]", (String) MH_super.invokeExact(l));
2088 assertEquals(""+l, (String) MH_this.invokeExact(l));
2089 assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
2090 try { assertEquals("inaccessible", Listie.lookup().findSpecial(
2091 String.class, "toString", methodType(String.class), Listie.class));
2092 } catch (IllegalAccessException ex) { } // OK
2093 Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
2094 assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
2095 * }</pre></blockquote>
2096 *
2097 * @param refc the class or interface from which the method is accessed
2098 * @param name the name of the method (which must not be "<init>")
2099 * @param type the type of the method, with the receiver argument omitted
2100 * @param specialCaller the proposed calling class to perform the {@code invokespecial}
2101 * @return the desired method handle
2102 * @throws NoSuchMethodException if the method does not exist
2103 * @throws IllegalAccessException if access checking fails,
2104 * or if the method is {@code static},
2105 * or if the method's variable arity modifier bit
2106 * is set and {@code asVarargsCollector} fails
2107 * @exception SecurityException if a security manager is present and it
2108 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2109 * @throws NullPointerException if any argument is null
2110 */
2111 public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
2112 Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
2113 checkSpecialCaller(specialCaller, refc);
2114 Lookup specialLookup = this.in(specialCaller);
2115 MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
2116 return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
2117 }
2118
2119 /**
2120 * Produces a method handle giving read access to a non-static field.
2121 * The type of the method handle will have a return type of the field's
2122 * value type.
2123 * The method handle's single argument will be the instance containing
2124 * the field.
2125 * Access checking is performed immediately on behalf of the lookup class.
2126 * @param refc the class or interface from which the method is accessed
2127 * @param name the field's name
2128 * @param type the field's type
2129 * @return a method handle which can load values from the field
2130 * @throws NoSuchFieldException if the field does not exist
2131 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
2132 * @exception SecurityException if a security manager is present and it
2133 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2134 * @throws NullPointerException if any argument is null
2135 * @see #findVarHandle(Class, String, Class)
2136 */
2137 public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2138 MemberName field = resolveOrFail(REF_getField, refc, name, type);
2139 return getDirectField(REF_getField, refc, field);
2140 }
2141
2142 /**
2143 * Produces a method handle giving write access to a non-static field.
2144 * The type of the method handle will have a void return type.
2145 * The method handle will take two arguments, the instance containing
2146 * the field, and the value to be stored.
2147 * The second argument will be of the field's value type.
2148 * Access checking is performed immediately on behalf of the lookup class.
2149 * @param refc the class or interface from which the method is accessed
2150 * @param name the field's name
2151 * @param type the field's type
2152 * @return a method handle which can store values into the field
2153 * @throws NoSuchFieldException if the field does not exist
2154 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
2155 * or {@code final}
2156 * @exception SecurityException if a security manager is present and it
2157 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2158 * @throws NullPointerException if any argument is null
2159 * @see #findVarHandle(Class, String, Class)
2160 */
2161 public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2162 MemberName field = resolveOrFail(REF_putField, refc, name, type);
2163 return getDirectField(REF_putField, refc, field);
2164 }
2165
2166 /**
2167 * Produces a VarHandle giving access to a non-static field {@code name}
2168 * of type {@code type} declared in a class of type {@code recv}.
2169 * The VarHandle's variable type is {@code type} and it has one
2170 * coordinate type, {@code recv}.
2171 * <p>
2172 * Access checking is performed immediately on behalf of the lookup
2173 * class.
2174 * <p>
2175 * Certain access modes of the returned VarHandle are unsupported under
2176 * the following conditions:
2209 * There are many possible NaN values that are considered to be
2210 * {@code NaN} in Java, although no IEEE 754 floating-point operation
2211 * provided by Java can distinguish between them. Operation failure can
2212 * occur if the expected or witness value is a NaN value and it is
2213 * transformed (perhaps in a platform specific manner) into another NaN
2214 * value, and thus has a different bitwise representation (see
2215 * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
2216 * details).
2217 * The values {@code -0.0} and {@code +0.0} have different bitwise
2218 * representations but are considered equal when using the primitive
2219 * {@code ==} operator. Operation failure can occur if, for example, a
2220 * numeric algorithm computes an expected value to be say {@code -0.0}
2221 * and previously computed the witness value to be say {@code +0.0}.
2222 * @param recv the receiver class, of type {@code R}, that declares the
2223 * non-static field
2224 * @param name the field's name
2225 * @param type the field's type, of type {@code T}
2226 * @return a VarHandle giving access to non-static fields.
2227 * @throws NoSuchFieldException if the field does not exist
2228 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
2229 * @exception SecurityException if a security manager is present and it
2230 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2231 * @throws NullPointerException if any argument is null
2232 * @since 9
2233 */
2234 public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2235 MemberName getField = resolveOrFail(REF_getField, recv, name, type);
2236 MemberName putField = resolveOrFail(REF_putField, recv, name, type);
2237 return getFieldVarHandle(REF_getField, REF_putField, recv, getField, putField);
2238 }
2239
2240 /**
2241 * Produces a method handle giving read access to a static field.
2242 * The type of the method handle will have a return type of the field's
2243 * value type.
2244 * The method handle will take no arguments.
2245 * Access checking is performed immediately on behalf of the lookup class.
2246 * <p>
2247 * If the returned method handle is invoked, the field's class will
2248 * be initialized, if it has not already been initialized.
2249 * @param refc the class or interface from which the method is accessed
2250 * @param name the field's name
2251 * @param type the field's type
2252 * @return a method handle which can load values from the field
2253 * @throws NoSuchFieldException if the field does not exist
2254 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
2255 * @exception SecurityException if a security manager is present and it
2256 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2257 * @throws NullPointerException if any argument is null
2258 */
2259 public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2260 MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
2261 return getDirectField(REF_getStatic, refc, field);
2262 }
2263
2264 /**
2265 * Produces a method handle giving write access to a static field.
2266 * The type of the method handle will have a void return type.
2267 * The method handle will take a single
2268 * argument, of the field's value type, the value to be stored.
2269 * Access checking is performed immediately on behalf of the lookup class.
2270 * <p>
2271 * If the returned method handle is invoked, the field's class will
2272 * be initialized, if it has not already been initialized.
2273 * @param refc the class or interface from which the method is accessed
2274 * @param name the field's name
2275 * @param type the field's type
2276 * @return a method handle which can store values into the field
2277 * @throws NoSuchFieldException if the field does not exist
2278 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
2279 * or is {@code final}
2280 * @exception SecurityException if a security manager is present and it
2281 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2282 * @throws NullPointerException if any argument is null
2283 */
2284 public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2285 MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
2286 return getDirectField(REF_putStatic, refc, field);
2287 }
2288
2289 /**
2290 * Produces a VarHandle giving access to a static field {@code name} of
2291 * type {@code type} declared in a class of type {@code decl}.
2292 * The VarHandle's variable type is {@code type} and it has no
2293 * coordinate types.
2294 * <p>
2295 * Access checking is performed immediately on behalf of the lookup
2296 * class.
2297 * <p>
2298 * If the returned VarHandle is operated on, the declaring class will be
2299 * initialized, if it has not already been initialized.
2300 * <p>
2334 * unexpectedly fail.
2335 * There are many possible NaN values that are considered to be
2336 * {@code NaN} in Java, although no IEEE 754 floating-point operation
2337 * provided by Java can distinguish between them. Operation failure can
2338 * occur if the expected or witness value is a NaN value and it is
2339 * transformed (perhaps in a platform specific manner) into another NaN
2340 * value, and thus has a different bitwise representation (see
2341 * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
2342 * details).
2343 * The values {@code -0.0} and {@code +0.0} have different bitwise
2344 * representations but are considered equal when using the primitive
2345 * {@code ==} operator. Operation failure can occur if, for example, a
2346 * numeric algorithm computes an expected value to be say {@code -0.0}
2347 * and previously computed the witness value to be say {@code +0.0}.
2348 * @param decl the class that declares the static field
2349 * @param name the field's name
2350 * @param type the field's type, of type {@code T}
2351 * @return a VarHandle giving access to a static field
2352 * @throws NoSuchFieldException if the field does not exist
2353 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
2354 * @exception SecurityException if a security manager is present and it
2355 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2356 * @throws NullPointerException if any argument is null
2357 * @since 9
2358 */
2359 public VarHandle findStaticVarHandle(Class<?> decl, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2360 MemberName getField = resolveOrFail(REF_getStatic, decl, name, type);
2361 MemberName putField = resolveOrFail(REF_putStatic, decl, name, type);
2362 return getFieldVarHandle(REF_getStatic, REF_putStatic, decl, getField, putField);
2363 }
2364
2365 /**
2366 * Produces an early-bound method handle for a non-static method.
2367 * The receiver must have a supertype {@code defc} in which a method
2368 * of the given name and type is accessible to the lookup class.
2369 * The method and all its argument types must be accessible to the lookup object.
2370 * The type of the method handle will be that of the method,
2371 * without any insertion of an additional receiver parameter.
2372 * The given receiver will be bound into the method handle,
2373 * so that every call to the method handle will invoke the
2374 * requested method on the given receiver.
2388 MethodHandle mh0 = lookup().findVirtual(defc, name, type);
2389 MethodHandle mh1 = mh0.bindTo(receiver);
2390 mh1 = mh1.withVarargs(mh0.isVarargsCollector());
2391 return mh1;
2392 * }</pre></blockquote>
2393 * where {@code defc} is either {@code receiver.getClass()} or a super
2394 * type of that class, in which the requested method is accessible
2395 * to the lookup class.
2396 * (Unlike {@code bind}, {@code bindTo} does not preserve variable arity.
2397 * Also, {@code bindTo} may throw a {@code ClassCastException} in instances where {@code bind} would
2398 * throw an {@code IllegalAccessException}, as in the case where the member is {@code protected} and
2399 * the receiver is restricted by {@code findVirtual} to the lookup class.)
2400 * @param receiver the object from which the method is accessed
2401 * @param name the name of the method
2402 * @param type the type of the method, with the receiver argument omitted
2403 * @return the desired method handle
2404 * @throws NoSuchMethodException if the method does not exist
2405 * @throws IllegalAccessException if access checking fails
2406 * or if the method's variable arity modifier bit
2407 * is set and {@code asVarargsCollector} fails
2408 * @exception SecurityException if a security manager is present and it
2409 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2410 * @throws NullPointerException if any argument is null
2411 * @see MethodHandle#bindTo
2412 * @see #findVirtual
2413 */
2414 public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2415 Class<? extends Object> refc = receiver.getClass(); // may get NPE
2416 MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
2417 MethodHandle mh = getDirectMethodNoRestrictInvokeSpecial(refc, method, findBoundCallerClass(method));
2418 if (!mh.type().leadingReferenceParameter().isAssignableFrom(receiver.getClass())) {
2419 throw new IllegalAccessException("The restricted defining class " +
2420 mh.type().leadingReferenceParameter().getName() +
2421 " is not assignable from receiver class " +
2422 receiver.getClass().getName());
2423 }
2424 return mh.bindArgumentL(0, receiver).setVarargs(method);
2425 }
2426
2427 /**
2428 * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
2690 * @since 9
2691 */
2692 public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
2693 MemberName getField = new MemberName(f, false);
2694 MemberName putField = new MemberName(f, true);
2695 return getFieldVarHandleNoSecurityManager(getField.getReferenceKind(), putField.getReferenceKind(),
2696 f.getDeclaringClass(), getField, putField);
2697 }
2698
2699 /**
2700 * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
2701 * created by this lookup object or a similar one.
2702 * Security and access checks are performed to ensure that this lookup object
2703 * is capable of reproducing the target method handle.
2704 * This means that the cracking may fail if target is a direct method handle
2705 * but was created by an unrelated lookup object.
2706 * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
2707 * and was created by a lookup object for a different class.
2708 * @param target a direct method handle to crack into symbolic reference components
2709 * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
2710 * @exception SecurityException if a security manager is present and it
2711 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2712 * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
2713 * @exception NullPointerException if the target is {@code null}
2714 * @see MethodHandleInfo
2715 * @since 1.8
2716 */
2717 public MethodHandleInfo revealDirect(MethodHandle target) {
2718 MemberName member = target.internalMemberName();
2719 if (member == null || (!member.isResolved() &&
2720 !member.isMethodHandleInvoke() &&
2721 !member.isVarHandleMethodInvoke()))
2722 throw newIllegalArgumentException("not a direct method handle");
2723 Class<?> defc = member.getDeclaringClass();
2724 byte refKind = member.getReferenceKind();
2725 assert(MethodHandleNatives.refKindIsValid(refKind));
2726 if (refKind == REF_invokeSpecial && !target.isInvokeSpecial())
2727 // Devirtualized method invocation is usually formally virtual.
2728 // To avoid creating extra MemberName objects for this common case,
2729 // we encode this extra degree of freedom using MH.isInvokeSpecial.
2730 refKind = REF_invokeVirtual;
2731 if (refKind == REF_invokeVirtual && defc.isInterface())
2732 // Symbolic reference is through interface but resolves to Object method (toString, etc.)
2733 refKind = REF_invokeInterface;
|
257 }
258 return Lookup.newLookup(targetClass, newPreviousClass, newModes);
259 }
260
261 /**
262 * Performs an unchecked "crack" of a
263 * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
264 * The result is as if the user had obtained a lookup object capable enough
265 * to crack the target method handle, called
266 * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
267 * on the target to obtain its symbolic reference, and then called
268 * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
269 * to resolve the symbolic reference to a member.
270 * <p>
271 * If there is a security manager, its {@code checkPermission} method
272 * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
273 * @param <T> the desired type of the result, either {@link Member} or a subtype
274 * @param target a direct method handle to crack into symbolic reference components
275 * @param expected a class object representing the desired result type {@code T}
276 * @return a reference to the method, constructor, or field object
277 * @throws SecurityException if the caller is not privileged to call {@code setAccessible}
278 * @throws NullPointerException if either argument is {@code null}
279 * @throws IllegalArgumentException if the target is not a direct method handle
280 * @throws ClassCastException if the member is not of the expected type
281 * @since 1.8
282 */
283 public static <T extends Member> T
284 reflectAs(Class<T> expected, MethodHandle target) {
285 SecurityManager smgr = System.getSecurityManager();
286 if (smgr != null) smgr.checkPermission(ACCESS_PERMISSION);
287 Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup
288 return lookup.revealDirect(target).reflectAs(expected, lookup);
289 }
290 // Copied from AccessibleObject, as used by Method.setAccessible, etc.:
291 private static final java.security.Permission ACCESS_PERMISSION =
292 new ReflectPermission("suppressAccessChecks");
293
294 /**
295 * A <em>lookup object</em> is a factory for creating method handles,
296 * when the creation requires access checking.
297 * Method handles do not perform
298 * access checks when they are called, but rather when they are created.
299 * Therefore, method handle access
300 * restrictions must be enforced when a method handle is created.
1737 * If the returned method handle is invoked, the method's class will
1738 * be initialized, if it has not already been initialized.
1739 * <p><b>Example:</b>
1740 * <blockquote><pre>{@code
1741 import static java.lang.invoke.MethodHandles.*;
1742 import static java.lang.invoke.MethodType.*;
1743 ...
1744 MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
1745 "asList", methodType(List.class, Object[].class));
1746 assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
1747 * }</pre></blockquote>
1748 * @param refc the class from which the method is accessed
1749 * @param name the name of the method
1750 * @param type the type of the method
1751 * @return the desired method handle
1752 * @throws NoSuchMethodException if the method does not exist
1753 * @throws IllegalAccessException if access checking fails,
1754 * or if the method is not {@code static},
1755 * or if the method's variable arity modifier bit
1756 * is set and {@code asVarargsCollector} fails
1757 * @throws SecurityException if a security manager is present and it
1758 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1759 * @throws NullPointerException if any argument is null
1760 */
1761 public
1762 MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1763 MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
1764 return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerClass(method));
1765 }
1766
1767 /**
1768 * Produces a method handle for a virtual method.
1769 * The type of the method handle will be that of the method,
1770 * with the receiver type (usually {@code refc}) prepended.
1771 * The method and all its argument types must be accessible to the lookup object.
1772 * <p>
1773 * When called, the handle will treat the first argument as a receiver
1774 * and, for non-private methods, dispatch on the receiver's type to determine which method
1775 * implementation to enter.
1776 * For private methods the named method in {@code refc} will be invoked on the receiver.
1777 * (The dispatching action is identical with that performed by an
1822 assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
1823 // constructor "internal method" must be accessed differently:
1824 MethodType MT_newString = methodType(void.class); //()V for new String()
1825 try { assertEquals("impossible", lookup()
1826 .findVirtual(String.class, "<init>", MT_newString));
1827 } catch (NoSuchMethodException ex) { } // OK
1828 MethodHandle MH_newString = publicLookup()
1829 .findConstructor(String.class, MT_newString);
1830 assertEquals("", (String) MH_newString.invokeExact());
1831 * }</pre></blockquote>
1832 *
1833 * @param refc the class or interface from which the method is accessed
1834 * @param name the name of the method
1835 * @param type the type of the method, with the receiver argument omitted
1836 * @return the desired method handle
1837 * @throws NoSuchMethodException if the method does not exist
1838 * @throws IllegalAccessException if access checking fails,
1839 * or if the method is {@code static},
1840 * or if the method's variable arity modifier bit
1841 * is set and {@code asVarargsCollector} fails
1842 * @throws SecurityException if a security manager is present and it
1843 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1844 * @throws NullPointerException if any argument is null
1845 */
1846 public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1847 if (refc == MethodHandle.class) {
1848 MethodHandle mh = findVirtualForMH(name, type);
1849 if (mh != null) return mh;
1850 } else if (refc == VarHandle.class) {
1851 MethodHandle mh = findVirtualForVH(name, type);
1852 if (mh != null) return mh;
1853 }
1854 byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
1855 MemberName method = resolveOrFail(refKind, refc, name, type);
1856 return getDirectMethod(refKind, refc, method, findBoundCallerClass(method));
1857 }
1858 private MethodHandle findVirtualForMH(String name, MethodType type) {
1859 // these names require special lookups because of the implicit MethodType argument
1860 if ("invoke".equals(name))
1861 return invoker(type);
1862 if ("invokeExact".equals(name))
1896 MethodHandle MH_newArrayList = publicLookup().findConstructor(
1897 ArrayList.class, methodType(void.class, Collection.class));
1898 Collection orig = Arrays.asList("x", "y");
1899 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
1900 assert(orig != copy);
1901 assertEquals(orig, copy);
1902 // a variable-arity constructor:
1903 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
1904 ProcessBuilder.class, methodType(void.class, String[].class));
1905 ProcessBuilder pb = (ProcessBuilder)
1906 MH_newProcessBuilder.invoke("x", "y", "z");
1907 assertEquals("[x, y, z]", pb.command().toString());
1908 * }</pre></blockquote>
1909 * @param refc the class or interface from which the method is accessed
1910 * @param type the type of the method, with the receiver argument omitted, and a void return type
1911 * @return the desired method handle
1912 * @throws NoSuchMethodException if the constructor does not exist
1913 * @throws IllegalAccessException if access checking fails
1914 * or if the method's variable arity modifier bit
1915 * is set and {@code asVarargsCollector} fails
1916 * @throws SecurityException if a security manager is present and it
1917 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1918 * @throws NullPointerException if any argument is null
1919 */
1920 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1921 if (refc.isArray()) {
1922 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
1923 }
1924 String name = "<init>";
1925 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
1926 return getDirectConstructor(refc, ctor);
1927 }
1928
1929 /**
1930 * Looks up a class by name from the lookup context defined by this {@code Lookup} object.
1931 * This method attempts to locate, load, and link the class, and then determines whether
1932 * the class is accessible to this {@code Lookup} object. The static
1933 * initializer of the class is not run.
1934 * <p>
1935 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
1936 * loader, and the {@linkplain #lookupModes() lookup modes}.
1937 * <p>
1938 * Note that this method throws errors related to loading and linking as
1939 * specified in Sections 12.2 and 12.3 of <em>The Java Language
1940 * Specification</em>.
1941 *
1942 * @param targetName the fully qualified name of the class to be looked up.
1943 * @return the requested class.
1944 * @throws SecurityException if a security manager is present and it
1945 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1946 * @throws LinkageError if the linkage fails
1947 * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
1948 * @throws IllegalAccessException if the class is not accessible, using the allowed access
1949 * modes.
1950 * @throws SecurityException if a security manager is present and it
1951 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1952 *
1953 * @jls 12.2 Loading of Classes and Interfaces
1954 * @jls 12.3 Linking of Classes and Interfaces
1955 * @since 9
1956 */
1957 public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {
1958 Class<?> targetClass = Class.forName(targetName, false, lookupClass.getClassLoader());
1959 return accessClass(targetClass);
1960 }
1961
1962 /**
1963 * Determines if a class can be accessed from the lookup context defined by
1964 * this {@code Lookup} object. The static initializer of the class is not run.
1965 * <p>
1966 * If the {@code targetClass} is in the same module as the lookup class,
1967 * the lookup class is {@code LC} in module {@code M1} and
1968 * the previous lookup class is in module {@code M0} or
1969 * {@code null} if not present,
1970 * {@code targetClass} is accessible if and only if one of the following is true:
2005 * containing the previous lookup class, then {@code targetClass} is accessible
2006 * if and only if one of the following is true:
2007 * <ul>
2008 * <li>{@code targetClass} is in {@code M0} and {@code M1}
2009 * {@linkplain Module#reads reads} {@code M0} and the type is
2010 * in a package that is exported to at least {@code M1}.
2011 * <li>{@code targetClass} is in {@code M1} and {@code M0}
2012 * {@linkplain Module#reads reads} {@code M1} and the type is
2013 * in a package that is exported to at least {@code M0}.
2014 * <li>{@code targetClass} is in a third module {@code M2} and both {@code M0}
2015 * and {@code M1} reads {@code M2} and the type is in a package
2016 * that is exported to at least both {@code M0} and {@code M2}.
2017 * </ul>
2018 * <p>
2019 * Otherwise, {@code targetClass} is not accessible.
2020 *
2021 * @param targetClass the class to be access-checked
2022 * @return the class that has been access-checked
2023 * @throws IllegalAccessException if the class is not accessible from the lookup class
2024 * and previous lookup class, if present, using the allowed access modes.
2025 * @throws SecurityException if a security manager is present and it
2026 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2027 * @since 9
2028 * @see <a href="#cross-module-lookup">Cross-module lookups</a>
2029 */
2030 public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException {
2031 if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) {
2032 throw new MemberName(targetClass).makeAccessException("access violation", this);
2033 }
2034 checkSecurityManager(targetClass, null);
2035 return targetClass;
2036 }
2037
2038 /**
2039 * Produces an early-bound method handle for a virtual method.
2040 * It will bypass checks for overriding methods on the receiver,
2041 * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
2042 * instruction from within the explicitly specified {@code specialCaller}.
2043 * The type of the method handle will be that of the method,
2044 * with a suitably restricted receiver type prepended.
2045 * (The receiver type will be {@code specialCaller} or a subtype.)
2087 assertEquals("[]", (String) MH_super.invokeExact(l));
2088 assertEquals(""+l, (String) MH_this.invokeExact(l));
2089 assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
2090 try { assertEquals("inaccessible", Listie.lookup().findSpecial(
2091 String.class, "toString", methodType(String.class), Listie.class));
2092 } catch (IllegalAccessException ex) { } // OK
2093 Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
2094 assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
2095 * }</pre></blockquote>
2096 *
2097 * @param refc the class or interface from which the method is accessed
2098 * @param name the name of the method (which must not be "<init>")
2099 * @param type the type of the method, with the receiver argument omitted
2100 * @param specialCaller the proposed calling class to perform the {@code invokespecial}
2101 * @return the desired method handle
2102 * @throws NoSuchMethodException if the method does not exist
2103 * @throws IllegalAccessException if access checking fails,
2104 * or if the method is {@code static},
2105 * or if the method's variable arity modifier bit
2106 * is set and {@code asVarargsCollector} fails
2107 * @throws SecurityException if a security manager is present and it
2108 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2109 * @throws NullPointerException if any argument is null
2110 */
2111 public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
2112 Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
2113 checkSpecialCaller(specialCaller, refc);
2114 Lookup specialLookup = this.in(specialCaller);
2115 MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
2116 return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
2117 }
2118
2119 /**
2120 * Produces a method handle giving read access to a non-static field.
2121 * The type of the method handle will have a return type of the field's
2122 * value type.
2123 * The method handle's single argument will be the instance containing
2124 * the field.
2125 * Access checking is performed immediately on behalf of the lookup class.
2126 * @param refc the class or interface from which the method is accessed
2127 * @param name the field's name
2128 * @param type the field's type
2129 * @return a method handle which can load values from the field
2130 * @throws NoSuchFieldException if the field does not exist
2131 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
2132 * @throws SecurityException if a security manager is present and it
2133 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2134 * @throws NullPointerException if any argument is null
2135 * @see #findVarHandle(Class, String, Class)
2136 */
2137 public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2138 MemberName field = resolveOrFail(REF_getField, refc, name, type);
2139 return getDirectField(REF_getField, refc, field);
2140 }
2141
2142 /**
2143 * Produces a method handle giving write access to a non-static field.
2144 * The type of the method handle will have a void return type.
2145 * The method handle will take two arguments, the instance containing
2146 * the field, and the value to be stored.
2147 * The second argument will be of the field's value type.
2148 * Access checking is performed immediately on behalf of the lookup class.
2149 * @param refc the class or interface from which the method is accessed
2150 * @param name the field's name
2151 * @param type the field's type
2152 * @return a method handle which can store values into the field
2153 * @throws NoSuchFieldException if the field does not exist
2154 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
2155 * or {@code final}
2156 * @throws SecurityException if a security manager is present and it
2157 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2158 * @throws NullPointerException if any argument is null
2159 * @see #findVarHandle(Class, String, Class)
2160 */
2161 public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2162 MemberName field = resolveOrFail(REF_putField, refc, name, type);
2163 return getDirectField(REF_putField, refc, field);
2164 }
2165
2166 /**
2167 * Produces a VarHandle giving access to a non-static field {@code name}
2168 * of type {@code type} declared in a class of type {@code recv}.
2169 * The VarHandle's variable type is {@code type} and it has one
2170 * coordinate type, {@code recv}.
2171 * <p>
2172 * Access checking is performed immediately on behalf of the lookup
2173 * class.
2174 * <p>
2175 * Certain access modes of the returned VarHandle are unsupported under
2176 * the following conditions:
2209 * There are many possible NaN values that are considered to be
2210 * {@code NaN} in Java, although no IEEE 754 floating-point operation
2211 * provided by Java can distinguish between them. Operation failure can
2212 * occur if the expected or witness value is a NaN value and it is
2213 * transformed (perhaps in a platform specific manner) into another NaN
2214 * value, and thus has a different bitwise representation (see
2215 * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
2216 * details).
2217 * The values {@code -0.0} and {@code +0.0} have different bitwise
2218 * representations but are considered equal when using the primitive
2219 * {@code ==} operator. Operation failure can occur if, for example, a
2220 * numeric algorithm computes an expected value to be say {@code -0.0}
2221 * and previously computed the witness value to be say {@code +0.0}.
2222 * @param recv the receiver class, of type {@code R}, that declares the
2223 * non-static field
2224 * @param name the field's name
2225 * @param type the field's type, of type {@code T}
2226 * @return a VarHandle giving access to non-static fields.
2227 * @throws NoSuchFieldException if the field does not exist
2228 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
2229 * @throws SecurityException if a security manager is present and it
2230 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2231 * @throws NullPointerException if any argument is null
2232 * @since 9
2233 */
2234 public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2235 MemberName getField = resolveOrFail(REF_getField, recv, name, type);
2236 MemberName putField = resolveOrFail(REF_putField, recv, name, type);
2237 return getFieldVarHandle(REF_getField, REF_putField, recv, getField, putField);
2238 }
2239
2240 /**
2241 * Produces a method handle giving read access to a static field.
2242 * The type of the method handle will have a return type of the field's
2243 * value type.
2244 * The method handle will take no arguments.
2245 * Access checking is performed immediately on behalf of the lookup class.
2246 * <p>
2247 * If the returned method handle is invoked, the field's class will
2248 * be initialized, if it has not already been initialized.
2249 * @param refc the class or interface from which the method is accessed
2250 * @param name the field's name
2251 * @param type the field's type
2252 * @return a method handle which can load values from the field
2253 * @throws NoSuchFieldException if the field does not exist
2254 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
2255 * @throws SecurityException if a security manager is present and it
2256 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2257 * @throws NullPointerException if any argument is null
2258 */
2259 public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2260 MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
2261 return getDirectField(REF_getStatic, refc, field);
2262 }
2263
2264 /**
2265 * Produces a method handle giving write access to a static field.
2266 * The type of the method handle will have a void return type.
2267 * The method handle will take a single
2268 * argument, of the field's value type, the value to be stored.
2269 * Access checking is performed immediately on behalf of the lookup class.
2270 * <p>
2271 * If the returned method handle is invoked, the field's class will
2272 * be initialized, if it has not already been initialized.
2273 * @param refc the class or interface from which the method is accessed
2274 * @param name the field's name
2275 * @param type the field's type
2276 * @return a method handle which can store values into the field
2277 * @throws NoSuchFieldException if the field does not exist
2278 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
2279 * or is {@code final}
2280 * @throws SecurityException if a security manager is present and it
2281 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2282 * @throws NullPointerException if any argument is null
2283 */
2284 public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2285 MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
2286 return getDirectField(REF_putStatic, refc, field);
2287 }
2288
2289 /**
2290 * Produces a VarHandle giving access to a static field {@code name} of
2291 * type {@code type} declared in a class of type {@code decl}.
2292 * The VarHandle's variable type is {@code type} and it has no
2293 * coordinate types.
2294 * <p>
2295 * Access checking is performed immediately on behalf of the lookup
2296 * class.
2297 * <p>
2298 * If the returned VarHandle is operated on, the declaring class will be
2299 * initialized, if it has not already been initialized.
2300 * <p>
2334 * unexpectedly fail.
2335 * There are many possible NaN values that are considered to be
2336 * {@code NaN} in Java, although no IEEE 754 floating-point operation
2337 * provided by Java can distinguish between them. Operation failure can
2338 * occur if the expected or witness value is a NaN value and it is
2339 * transformed (perhaps in a platform specific manner) into another NaN
2340 * value, and thus has a different bitwise representation (see
2341 * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
2342 * details).
2343 * The values {@code -0.0} and {@code +0.0} have different bitwise
2344 * representations but are considered equal when using the primitive
2345 * {@code ==} operator. Operation failure can occur if, for example, a
2346 * numeric algorithm computes an expected value to be say {@code -0.0}
2347 * and previously computed the witness value to be say {@code +0.0}.
2348 * @param decl the class that declares the static field
2349 * @param name the field's name
2350 * @param type the field's type, of type {@code T}
2351 * @return a VarHandle giving access to a static field
2352 * @throws NoSuchFieldException if the field does not exist
2353 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
2354 * @throws SecurityException if a security manager is present and it
2355 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2356 * @throws NullPointerException if any argument is null
2357 * @since 9
2358 */
2359 public VarHandle findStaticVarHandle(Class<?> decl, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
2360 MemberName getField = resolveOrFail(REF_getStatic, decl, name, type);
2361 MemberName putField = resolveOrFail(REF_putStatic, decl, name, type);
2362 return getFieldVarHandle(REF_getStatic, REF_putStatic, decl, getField, putField);
2363 }
2364
2365 /**
2366 * Produces an early-bound method handle for a non-static method.
2367 * The receiver must have a supertype {@code defc} in which a method
2368 * of the given name and type is accessible to the lookup class.
2369 * The method and all its argument types must be accessible to the lookup object.
2370 * The type of the method handle will be that of the method,
2371 * without any insertion of an additional receiver parameter.
2372 * The given receiver will be bound into the method handle,
2373 * so that every call to the method handle will invoke the
2374 * requested method on the given receiver.
2388 MethodHandle mh0 = lookup().findVirtual(defc, name, type);
2389 MethodHandle mh1 = mh0.bindTo(receiver);
2390 mh1 = mh1.withVarargs(mh0.isVarargsCollector());
2391 return mh1;
2392 * }</pre></blockquote>
2393 * where {@code defc} is either {@code receiver.getClass()} or a super
2394 * type of that class, in which the requested method is accessible
2395 * to the lookup class.
2396 * (Unlike {@code bind}, {@code bindTo} does not preserve variable arity.
2397 * Also, {@code bindTo} may throw a {@code ClassCastException} in instances where {@code bind} would
2398 * throw an {@code IllegalAccessException}, as in the case where the member is {@code protected} and
2399 * the receiver is restricted by {@code findVirtual} to the lookup class.)
2400 * @param receiver the object from which the method is accessed
2401 * @param name the name of the method
2402 * @param type the type of the method, with the receiver argument omitted
2403 * @return the desired method handle
2404 * @throws NoSuchMethodException if the method does not exist
2405 * @throws IllegalAccessException if access checking fails
2406 * or if the method's variable arity modifier bit
2407 * is set and {@code asVarargsCollector} fails
2408 * @throws SecurityException if a security manager is present and it
2409 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2410 * @throws NullPointerException if any argument is null
2411 * @see MethodHandle#bindTo
2412 * @see #findVirtual
2413 */
2414 public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2415 Class<? extends Object> refc = receiver.getClass(); // may get NPE
2416 MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
2417 MethodHandle mh = getDirectMethodNoRestrictInvokeSpecial(refc, method, findBoundCallerClass(method));
2418 if (!mh.type().leadingReferenceParameter().isAssignableFrom(receiver.getClass())) {
2419 throw new IllegalAccessException("The restricted defining class " +
2420 mh.type().leadingReferenceParameter().getName() +
2421 " is not assignable from receiver class " +
2422 receiver.getClass().getName());
2423 }
2424 return mh.bindArgumentL(0, receiver).setVarargs(method);
2425 }
2426
2427 /**
2428 * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
2690 * @since 9
2691 */
2692 public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
2693 MemberName getField = new MemberName(f, false);
2694 MemberName putField = new MemberName(f, true);
2695 return getFieldVarHandleNoSecurityManager(getField.getReferenceKind(), putField.getReferenceKind(),
2696 f.getDeclaringClass(), getField, putField);
2697 }
2698
2699 /**
2700 * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
2701 * created by this lookup object or a similar one.
2702 * Security and access checks are performed to ensure that this lookup object
2703 * is capable of reproducing the target method handle.
2704 * This means that the cracking may fail if target is a direct method handle
2705 * but was created by an unrelated lookup object.
2706 * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
2707 * and was created by a lookup object for a different class.
2708 * @param target a direct method handle to crack into symbolic reference components
2709 * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
2710 * @throws SecurityException if a security manager is present and it
2711 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2712 * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
2713 * @throws NullPointerException if the target is {@code null}
2714 * @see MethodHandleInfo
2715 * @since 1.8
2716 */
2717 public MethodHandleInfo revealDirect(MethodHandle target) {
2718 MemberName member = target.internalMemberName();
2719 if (member == null || (!member.isResolved() &&
2720 !member.isMethodHandleInvoke() &&
2721 !member.isVarHandleMethodInvoke()))
2722 throw newIllegalArgumentException("not a direct method handle");
2723 Class<?> defc = member.getDeclaringClass();
2724 byte refKind = member.getReferenceKind();
2725 assert(MethodHandleNatives.refKindIsValid(refKind));
2726 if (refKind == REF_invokeSpecial && !target.isInvokeSpecial())
2727 // Devirtualized method invocation is usually formally virtual.
2728 // To avoid creating extra MemberName objects for this common case,
2729 // we encode this extra degree of freedom using MH.isInvokeSpecial.
2730 refKind = REF_invokeVirtual;
2731 if (refKind == REF_invokeVirtual && defc.isInterface())
2732 // Symbolic reference is through interface but resolves to Object method (toString, etc.)
2733 refKind = REF_invokeInterface;
|