993 assertEquals(orig, copy);
994 // a variable-arity constructor:
995 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
996 ProcessBuilder.class, methodType(void.class, String[].class));
997 ProcessBuilder pb = (ProcessBuilder)
998 MH_newProcessBuilder.invoke("x", "y", "z");
999 assertEquals("[x, y, z]", pb.command().toString());
1000 * }</pre></blockquote>
1001 * @param refc the class or interface from which the method is accessed
1002 * @param type the type of the method, with the receiver argument omitted, and a void return type
1003 * @return the desired method handle
1004 * @throws NoSuchMethodException if the constructor does not exist
1005 * @throws IllegalAccessException if access checking fails
1006 * or if the method's variable arity modifier bit
1007 * is set and {@code asVarargsCollector} fails
1008 * @exception SecurityException if a security manager is present and it
1009 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1010 * @throws NullPointerException if any argument is null
1011 */
1012 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1013 String name = "<init>";
1014 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
1015 return getDirectConstructor(refc, ctor);
1016 }
1017
1018 /**
1019 * Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
1020 * initializer of the class is not run.
1021 * <p>
1022 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
1023 * loader, and the {@linkplain #lookupModes() lookup modes}. In particular, the method first attempts to
1024 * load the requested class, and then determines whether the class is accessible to this lookup object.
1025 *
1026 * @param targetName the fully qualified name of the class to be looked up.
1027 * @return the requested class.
1028 * @exception SecurityException if a security manager is present and it
1029 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1030 * @throws LinkageError if the linkage fails
1031 * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
1032 * @throws IllegalAccessException if the class is not accessible, using the allowed access
2204 private static final Class<?> PUBLIC_LOOKUP_CLASS;
2205 static {
2206 PrivilegedAction<Class<?>> pa = new PrivilegedAction<Class<?>>() {
2207 public Class<?> run() {
2208 return createClass();
2209 }
2210 };
2211 PUBLIC_LOOKUP_CLASS = AccessController.doPrivileged(pa);
2212 }
2213
2214 /**
2215 * Lookup that is trusted minimally. It can only be used to create
2216 * method handles to publicly accessible members in exported packages.
2217 *
2218 * @see MethodHandles#publicLookup
2219 */
2220 static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_LOOKUP_CLASS, Lookup.PUBLIC);
2221 }
2222
2223 /**
2224 * Produces a method handle giving read access to elements of an array.
2225 * The type of the method handle will have a return type of the array's
2226 * element type. Its first argument will be the array type,
2227 * and the second will be {@code int}.
2228 * @param arrayClass an array type
2229 * @return a method handle which can load values from the given array type
2230 * @throws NullPointerException if the argument is null
2231 * @throws IllegalArgumentException if arrayClass is not an array type
2232 */
2233 public static
2234 MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
2235 return MethodHandleImpl.makeArrayElementAccessor(arrayClass, false);
2236 }
2237
2238 /**
2239 * Produces a method handle giving write access to elements of an array.
2240 * The type of the method handle will have a void return type.
2241 * Its last argument will be the array's element type.
2242 * The first and second arguments will be the array type and int.
2243 * @param arrayClass the class of an array
|
993 assertEquals(orig, copy);
994 // a variable-arity constructor:
995 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
996 ProcessBuilder.class, methodType(void.class, String[].class));
997 ProcessBuilder pb = (ProcessBuilder)
998 MH_newProcessBuilder.invoke("x", "y", "z");
999 assertEquals("[x, y, z]", pb.command().toString());
1000 * }</pre></blockquote>
1001 * @param refc the class or interface from which the method is accessed
1002 * @param type the type of the method, with the receiver argument omitted, and a void return type
1003 * @return the desired method handle
1004 * @throws NoSuchMethodException if the constructor does not exist
1005 * @throws IllegalAccessException if access checking fails
1006 * or if the method's variable arity modifier bit
1007 * is set and {@code asVarargsCollector} fails
1008 * @exception SecurityException if a security manager is present and it
1009 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1010 * @throws NullPointerException if any argument is null
1011 */
1012 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1013 if (refc.isArray()) {
1014 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
1015 }
1016 String name = "<init>";
1017 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
1018 return getDirectConstructor(refc, ctor);
1019 }
1020
1021 /**
1022 * Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
1023 * initializer of the class is not run.
1024 * <p>
1025 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
1026 * loader, and the {@linkplain #lookupModes() lookup modes}. In particular, the method first attempts to
1027 * load the requested class, and then determines whether the class is accessible to this lookup object.
1028 *
1029 * @param targetName the fully qualified name of the class to be looked up.
1030 * @return the requested class.
1031 * @exception SecurityException if a security manager is present and it
1032 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1033 * @throws LinkageError if the linkage fails
1034 * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
1035 * @throws IllegalAccessException if the class is not accessible, using the allowed access
2207 private static final Class<?> PUBLIC_LOOKUP_CLASS;
2208 static {
2209 PrivilegedAction<Class<?>> pa = new PrivilegedAction<Class<?>>() {
2210 public Class<?> run() {
2211 return createClass();
2212 }
2213 };
2214 PUBLIC_LOOKUP_CLASS = AccessController.doPrivileged(pa);
2215 }
2216
2217 /**
2218 * Lookup that is trusted minimally. It can only be used to create
2219 * method handles to publicly accessible members in exported packages.
2220 *
2221 * @see MethodHandles#publicLookup
2222 */
2223 static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_LOOKUP_CLASS, Lookup.PUBLIC);
2224 }
2225
2226 /**
2227 * Produces a method handle that can construct arrays of a desired type.
2228 * The return type of the method handle will be the array type.
2229 * The type of its sole argument will be {@code int}, which specifies the size of the array.
2230 * @param arrayClass an array type
2231 * @return a method handle which can create arrays of the given type
2232 * @throws NullPointerException if the argument is {@code null}
2233 * @throws IllegalArgumentException if {@code arrayClass} is not an array type
2234 * @since 9
2235 */
2236 public static
2237 MethodHandle arrayConstructor(Class<?> arrayClass) throws IllegalArgumentException {
2238 if (!arrayClass.isArray()) {
2239 throw newIllegalArgumentException("not an array class: " + arrayClass.getName());
2240 }
2241 MethodHandle ani = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_Array_newInstance).
2242 bindTo(arrayClass.getComponentType());
2243 return ani.asType(ani.type().changeReturnType(arrayClass));
2244 }
2245
2246 /**
2247 * Produces a method handle giving read access to elements of an array.
2248 * The type of the method handle will have a return type of the array's
2249 * element type. Its first argument will be the array type,
2250 * and the second will be {@code int}.
2251 * @param arrayClass an array type
2252 * @return a method handle which can load values from the given array type
2253 * @throws NullPointerException if the argument is null
2254 * @throws IllegalArgumentException if arrayClass is not an array type
2255 */
2256 public static
2257 MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
2258 return MethodHandleImpl.makeArrayElementAccessor(arrayClass, false);
2259 }
2260
2261 /**
2262 * Produces a method handle giving write access to elements of an array.
2263 * The type of the method handle will have a void return type.
2264 * Its last argument will be the array's element type.
2265 * The first and second arguments will be the array type and int.
2266 * @param arrayClass the class of an array
|