< prev index next >

src/java.base/share/classes/java/lang/invoke/MethodHandles.java

Print this page
rev 14297 : 8155106: MHs.Lookup.findConstructor returns handles for array classes


 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


< prev index next >