2774 * If the returned method handle is invoked, the constructor's class will
2775 * be initialized, if it has not already been initialized.
2776 * <p><b>Example:</b>
2777 * {@snippet lang="java" :
2778 import static java.lang.invoke.MethodHandles.*;
2779 import static java.lang.invoke.MethodType.*;
2780 ...
2781 MethodHandle MH_newArrayList = publicLookup().findConstructor(
2782 ArrayList.class, methodType(void.class, Collection.class));
2783 Collection orig = Arrays.asList("x", "y");
2784 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
2785 assert(orig != copy);
2786 assertEquals(orig, copy);
2787 // a variable-arity constructor:
2788 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
2789 ProcessBuilder.class, methodType(void.class, String[].class));
2790 ProcessBuilder pb = (ProcessBuilder)
2791 MH_newProcessBuilder.invoke("x", "y", "z");
2792 assertEquals("[x, y, z]", pb.command().toString());
2793 * }
2794 * @param refc the class or interface from which the method is accessed
2795 * @param type the type of the method, with the receiver argument omitted, and a void return type
2796 * @return the desired method handle
2797 * @throws NoSuchMethodException if the constructor does not exist
2798 * @throws IllegalAccessException if access checking fails
2799 * or if the method's variable arity modifier bit
2800 * is set and {@code asVarargsCollector} fails
2801 * @throws SecurityException if a security manager is present and it
2802 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2803 * @throws NullPointerException if any argument is null
2804 */
2805 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2806 if (refc.isArray()) {
2807 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
2808 }
2809 String name = ConstantDescs.INIT_NAME;
2810 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
2811 return getDirectConstructor(refc, ctor);
2812 }
2813
2814 /**
2815 * Looks up a class by name from the lookup context defined by this {@code Lookup} object,
2816 * <a href="MethodHandles.Lookup.html#equiv">as if resolved</a> by an {@code ldc} instruction.
2817 * Such a resolution, as specified in JVMS {@jvms 5.4.3.1}, attempts to locate and load the class,
2818 * and then determines whether the class is accessible to this lookup object.
2819 * <p>
2820 * For a class or an interface, the name is the {@linkplain ClassLoader##binary-name binary name}.
2821 * For an array class of {@code n} dimensions, the name begins with {@code n} occurrences
2822 * of {@code '['} and followed by the element type as encoded in the
2823 * {@linkplain Class##nameFormat table} specified in {@link Class#getName}.
2824 * <p>
2825 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class},
2826 * its class loader, and the {@linkplain #lookupModes() lookup modes}.
2827 *
2828 * @param targetName the {@linkplain ClassLoader##binary-name binary name} of the class
4057 final boolean doRestrict = false;
4058 final boolean checkSecurity = true;
4059 return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
4060 }
4061 /** Check access and get the requested method, eliding security manager checks. */
4062 private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
4063 final boolean doRestrict = true;
4064 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
4065 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
4066 }
4067 /** Common code for all methods; do not call directly except from immediately above. */
4068 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
4069 boolean checkSecurity,
4070 boolean doRestrict,
4071 Lookup boundCaller) throws IllegalAccessException {
4072 checkMethod(refKind, refc, method);
4073 // Optionally check with the security manager; this isn't needed for unreflect* calls.
4074 if (checkSecurity)
4075 checkSecurityManager(refc, method);
4076 assert(!method.isMethodHandleInvoke());
4077
4078 if (refKind == REF_invokeSpecial &&
4079 refc != lookupClass() &&
4080 !refc.isInterface() && !lookupClass().isInterface() &&
4081 refc != lookupClass().getSuperclass() &&
4082 refc.isAssignableFrom(lookupClass())) {
4083 assert(!method.getName().equals(ConstantDescs.INIT_NAME)); // not this code path
4084
4085 // Per JVMS 6.5, desc. of invokespecial instruction:
4086 // If the method is in a superclass of the LC,
4087 // and if our original search was above LC.super,
4088 // repeat the search (symbolic lookup) from LC.super
4089 // and continue with the direct superclass of that class,
4090 // and so forth, until a match is found or no further superclasses exist.
4091 // FIXME: MemberName.resolve should handle this instead.
4092 Class<?> refcAsSuper = lookupClass();
4093 MemberName m2;
4094 do {
4095 refcAsSuper = refcAsSuper.getSuperclass();
4096 m2 = new MemberName(refcAsSuper,
4097 method.getName(),
|
2774 * If the returned method handle is invoked, the constructor's class will
2775 * be initialized, if it has not already been initialized.
2776 * <p><b>Example:</b>
2777 * {@snippet lang="java" :
2778 import static java.lang.invoke.MethodHandles.*;
2779 import static java.lang.invoke.MethodType.*;
2780 ...
2781 MethodHandle MH_newArrayList = publicLookup().findConstructor(
2782 ArrayList.class, methodType(void.class, Collection.class));
2783 Collection orig = Arrays.asList("x", "y");
2784 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
2785 assert(orig != copy);
2786 assertEquals(orig, copy);
2787 // a variable-arity constructor:
2788 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
2789 ProcessBuilder.class, methodType(void.class, String[].class));
2790 ProcessBuilder pb = (ProcessBuilder)
2791 MH_newProcessBuilder.invoke("x", "y", "z");
2792 assertEquals("[x, y, z]", pb.command().toString());
2793 * }
2794 *
2795 *
2796 * @param refc the class or interface from which the method is accessed
2797 * @param type the type of the method, with the receiver argument omitted, and a void return type
2798 * @return the desired method handle
2799 * @throws NoSuchMethodException if the constructor does not exist
2800 * @throws IllegalAccessException if access checking fails
2801 * or if the method's variable arity modifier bit
2802 * is set and {@code asVarargsCollector} fails
2803 * @throws SecurityException if a security manager is present and it
2804 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2805 * @throws NullPointerException if any argument is null
2806 */
2807 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2808 if (refc.isArray()) {
2809 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
2810 }
2811 if (type.returnType() != void.class) {
2812 throw new NoSuchMethodException("Constructors must have void return type: " + refc.getName());
2813 }
2814 String name = ConstantDescs.INIT_NAME;
2815 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
2816 return getDirectConstructor(refc, ctor);
2817 }
2818
2819 /**
2820 * Looks up a class by name from the lookup context defined by this {@code Lookup} object,
2821 * <a href="MethodHandles.Lookup.html#equiv">as if resolved</a> by an {@code ldc} instruction.
2822 * Such a resolution, as specified in JVMS {@jvms 5.4.3.1}, attempts to locate and load the class,
2823 * and then determines whether the class is accessible to this lookup object.
2824 * <p>
2825 * For a class or an interface, the name is the {@linkplain ClassLoader##binary-name binary name}.
2826 * For an array class of {@code n} dimensions, the name begins with {@code n} occurrences
2827 * of {@code '['} and followed by the element type as encoded in the
2828 * {@linkplain Class##nameFormat table} specified in {@link Class#getName}.
2829 * <p>
2830 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class},
2831 * its class loader, and the {@linkplain #lookupModes() lookup modes}.
2832 *
2833 * @param targetName the {@linkplain ClassLoader##binary-name binary name} of the class
4062 final boolean doRestrict = false;
4063 final boolean checkSecurity = true;
4064 return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
4065 }
4066 /** Check access and get the requested method, eliding security manager checks. */
4067 private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
4068 final boolean doRestrict = true;
4069 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
4070 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
4071 }
4072 /** Common code for all methods; do not call directly except from immediately above. */
4073 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
4074 boolean checkSecurity,
4075 boolean doRestrict,
4076 Lookup boundCaller) throws IllegalAccessException {
4077 checkMethod(refKind, refc, method);
4078 // Optionally check with the security manager; this isn't needed for unreflect* calls.
4079 if (checkSecurity)
4080 checkSecurityManager(refc, method);
4081 assert(!method.isMethodHandleInvoke());
4082 if (refKind == REF_invokeSpecial &&
4083 refc != lookupClass() &&
4084 !refc.isInterface() && !lookupClass().isInterface() &&
4085 refc != lookupClass().getSuperclass() &&
4086 refc.isAssignableFrom(lookupClass())) {
4087 assert(!method.getName().equals(ConstantDescs.INIT_NAME)); // not this code path
4088
4089 // Per JVMS 6.5, desc. of invokespecial instruction:
4090 // If the method is in a superclass of the LC,
4091 // and if our original search was above LC.super,
4092 // repeat the search (symbolic lookup) from LC.super
4093 // and continue with the direct superclass of that class,
4094 // and so forth, until a match is found or no further superclasses exist.
4095 // FIXME: MemberName.resolve should handle this instead.
4096 Class<?> refcAsSuper = lookupClass();
4097 MemberName m2;
4098 do {
4099 refcAsSuper = refcAsSuper.getSuperclass();
4100 m2 = new MemberName(refcAsSuper,
4101 method.getName(),
|