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