1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandles.java Sun Sep 14 19:27:44 2014 +0200
1.3 @@ -0,0 +1,1222 @@
1.4 +/*
1.5 + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.lang.invoke;
1.30 +
1.31 +import java.lang.reflect.*;
1.32 +
1.33 +/**
1.34 + * This class consists exclusively of static methods that operate on or return
1.35 + * method handles. They fall into several categories:
1.36 + * <ul>
1.37 + * <li>Lookup methods which help create method handles for methods and fields.
1.38 + * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
1.39 + * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
1.40 + * </ul>
1.41 + * <p>
1.42 + * @author John Rose, JSR 292 EG
1.43 + * @since 1.7
1.44 + */
1.45 +public class MethodHandles {
1.46 +
1.47 + private MethodHandles() { } // do not instantiate
1.48 +
1.49 + //// Method handle creation from ordinary methods.
1.50 +
1.51 + /**
1.52 + * Returns a {@link Lookup lookup object} with
1.53 + * full capabilities to emulate all supported bytecode behaviors of the caller.
1.54 + * These capabilities include <a href="MethodHandles.Lookup.html#privacc">private access</a> to the caller.
1.55 + * Factory methods on the lookup object can create
1.56 + * <a href="MethodHandleInfo.html#directmh">direct method handles</a>
1.57 + * for any member that the caller has access to via bytecodes,
1.58 + * including protected and private fields and methods.
1.59 + * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
1.60 + * Do not store it in place where untrusted code can access it.
1.61 + * <p>
1.62 + * This method is caller sensitive, which means that it may return different
1.63 + * values to different callers.
1.64 + * <p>
1.65 + * For any given caller class {@code C}, the lookup object returned by this call
1.66 + * has equivalent capabilities to any lookup object
1.67 + * supplied by the JVM to the bootstrap method of an
1.68 + * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
1.69 + * executing in the same caller class {@code C}.
1.70 + * @return a lookup object for the caller of this method, with private access
1.71 + */
1.72 +// @CallerSensitive
1.73 + public static Lookup lookup() {
1.74 + throw new IllegalStateException("Implement me!");
1.75 +// return new Lookup(Reflection.getCallerClass());
1.76 + }
1.77 +
1.78 + /**
1.79 + * Returns a {@link Lookup lookup object} which is trusted minimally.
1.80 + * It can only be used to create method handles to
1.81 + * publicly accessible fields and methods.
1.82 + * <p>
1.83 + * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
1.84 + * of this lookup object will be {@link java.lang.Object}.
1.85 + *
1.86 + * <p style="font-size:smaller;">
1.87 + * <em>Discussion:</em>
1.88 + * The lookup class can be changed to any other class {@code C} using an expression of the form
1.89 + * {@link Lookup#in publicLookup().in(C.class)}.
1.90 + * Since all classes have equal access to public names,
1.91 + * such a change would confer no new access rights.
1.92 + * A public lookup object is always subject to
1.93 + * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
1.94 + * Also, it cannot access
1.95 + * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
1.96 + * @return a lookup object which is trusted minimally
1.97 + */
1.98 + public static Lookup publicLookup() {
1.99 + return Lookup.PUBLIC_LOOKUP;
1.100 + }
1.101 +
1.102 + /**
1.103 + * Performs an unchecked "crack" of a
1.104 + * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
1.105 + * The result is as if the user had obtained a lookup object capable enough
1.106 + * to crack the target method handle, called
1.107 + * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
1.108 + * on the target to obtain its symbolic reference, and then called
1.109 + * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
1.110 + * to resolve the symbolic reference to a member.
1.111 + * <p>
1.112 + * If there is a security manager, its {@code checkPermission} method
1.113 + * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
1.114 + * @param <T> the desired type of the result, either {@link Member} or a subtype
1.115 + * @param target a direct method handle to crack into symbolic reference components
1.116 + * @param expected a class object representing the desired result type {@code T}
1.117 + * @return a reference to the method, constructor, or field object
1.118 + * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
1.119 + * @exception NullPointerException if either argument is {@code null}
1.120 + * @exception IllegalArgumentException if the target is not a direct method handle
1.121 + * @exception ClassCastException if the member is not of the expected type
1.122 + * @since 1.8
1.123 + */
1.124 + public static <T extends Member> T
1.125 + reflectAs(Class<T> expected, MethodHandle target) {
1.126 + throw new IllegalStateException();
1.127 + }
1.128 + // Copied from AccessibleObject, as used by Method.setAccessible, etc.:
1.129 +// static final private java.security.Permission ACCESS_PERMISSION =
1.130 +// new ReflectPermission("suppressAccessChecks");
1.131 +
1.132 + static Lookup findFor(Class<?> clazz) {
1.133 + Object o = clazz;
1.134 + if (o instanceof Class) {
1.135 + return new Lookup(clazz, Lookup.ALL_MODES);
1.136 + }
1.137 + throw new IllegalArgumentException("Expecting class: " + o);
1.138 + }
1.139 +
1.140 + /**
1.141 + * A <em>lookup object</em> is a factory for creating method handles,
1.142 + * when the creation requires access checking.
1.143 + * Method handles do not perform
1.144 + * access checks when they are called, but rather when they are created.
1.145 + * Therefore, method handle access
1.146 + * restrictions must be enforced when a method handle is created.
1.147 + * The caller class against which those restrictions are enforced
1.148 + * is known as the {@linkplain #lookupClass lookup class}.
1.149 + * <p>
1.150 + * A lookup class which needs to create method handles will call
1.151 + * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
1.152 + * When the {@code Lookup} factory object is created, the identity of the lookup class is
1.153 + * determined, and securely stored in the {@code Lookup} object.
1.154 + * The lookup class (or its delegates) may then use factory methods
1.155 + * on the {@code Lookup} object to create method handles for access-checked members.
1.156 + * This includes all methods, constructors, and fields which are allowed to the lookup class,
1.157 + * even private ones.
1.158 + *
1.159 + * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
1.160 + * The factory methods on a {@code Lookup} object correspond to all major
1.161 + * use cases for methods, constructors, and fields.
1.162 + * Each method handle created by a factory method is the functional
1.163 + * equivalent of a particular <em>bytecode behavior</em>.
1.164 + * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.)
1.165 + * Here is a summary of the correspondence between these factory methods and
1.166 + * the behavior the resulting method handles:
1.167 + * <table border=1 cellpadding=5 summary="lookup method behaviors">
1.168 + * <tr>
1.169 + * <th><a name="equiv"></a>lookup expression</th>
1.170 + * <th>member</th>
1.171 + * <th>bytecode behavior</th>
1.172 + * </tr>
1.173 + * <tr>
1.174 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
1.175 + * <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
1.176 + * </tr>
1.177 + * <tr>
1.178 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
1.179 + * <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
1.180 + * </tr>
1.181 + * <tr>
1.182 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
1.183 + * <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
1.184 + * </tr>
1.185 + * <tr>
1.186 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
1.187 + * <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
1.188 + * </tr>
1.189 + * <tr>
1.190 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
1.191 + * <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
1.192 + * </tr>
1.193 + * <tr>
1.194 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
1.195 + * <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
1.196 + * </tr>
1.197 + * <tr>
1.198 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
1.199 + * <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
1.200 + * </tr>
1.201 + * <tr>
1.202 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
1.203 + * <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
1.204 + * </tr>
1.205 + * <tr>
1.206 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
1.207 + * <td>({@code static})?<br>{@code FT f;}</td><td>{@code (FT) aField.get(thisOrNull);}</td>
1.208 + * </tr>
1.209 + * <tr>
1.210 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
1.211 + * <td>({@code static})?<br>{@code FT f;}</td><td>{@code aField.set(thisOrNull, arg);}</td>
1.212 + * </tr>
1.213 + * <tr>
1.214 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
1.215 + * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
1.216 + * </tr>
1.217 + * <tr>
1.218 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
1.219 + * <td>{@code C(A*);}</td><td>{@code (C) aConstructor.newInstance(arg*);}</td>
1.220 + * </tr>
1.221 + * <tr>
1.222 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
1.223 + * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
1.224 + * </tr>
1.225 + * </table>
1.226 + *
1.227 + * Here, the type {@code C} is the class or interface being searched for a member,
1.228 + * documented as a parameter named {@code refc} in the lookup methods.
1.229 + * The method type {@code MT} is composed from the return type {@code T}
1.230 + * and the sequence of argument types {@code A*}.
1.231 + * The constructor also has a sequence of argument types {@code A*} and
1.232 + * is deemed to return the newly-created object of type {@code C}.
1.233 + * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
1.234 + * The formal parameter {@code this} stands for the self-reference of type {@code C};
1.235 + * if it is present, it is always the leading argument to the method handle invocation.
1.236 + * (In the case of some {@code protected} members, {@code this} may be
1.237 + * restricted in type to the lookup class; see below.)
1.238 + * The name {@code arg} stands for all the other method handle arguments.
1.239 + * In the code examples for the Core Reflection API, the name {@code thisOrNull}
1.240 + * stands for a null reference if the accessed method or field is static,
1.241 + * and {@code this} otherwise.
1.242 + * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
1.243 + * for reflective objects corresponding to the given members.
1.244 + * <p>
1.245 + * In cases where the given member is of variable arity (i.e., a method or constructor)
1.246 + * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
1.247 + * In all other cases, the returned method handle will be of fixed arity.
1.248 + * <p style="font-size:smaller;">
1.249 + * <em>Discussion:</em>
1.250 + * The equivalence between looked-up method handles and underlying
1.251 + * class members and bytecode behaviors
1.252 + * can break down in a few ways:
1.253 + * <ul style="font-size:smaller;">
1.254 + * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
1.255 + * the lookup can still succeed, even when there is no equivalent
1.256 + * Java expression or bytecoded constant.
1.257 + * <li>Likewise, if {@code T} or {@code MT}
1.258 + * is not symbolically accessible from the lookup class's loader,
1.259 + * the lookup can still succeed.
1.260 + * For example, lookups for {@code MethodHandle.invokeExact} and
1.261 + * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
1.262 + * <li>If there is a security manager installed, it can forbid the lookup
1.263 + * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
1.264 + * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
1.265 + * constant is not subject to security manager checks.
1.266 + * <li>If the looked-up method has a
1.267 + * <a href="MethodHandle.html#maxarity">very large arity</a>,
1.268 + * the method handle creation may fail, due to the method handle
1.269 + * type having too many parameters.
1.270 + * </ul>
1.271 + *
1.272 + * <h1><a name="access"></a>Access checking</h1>
1.273 + * Access checks are applied in the factory methods of {@code Lookup},
1.274 + * when a method handle is created.
1.275 + * This is a key difference from the Core Reflection API, since
1.276 + * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
1.277 + * performs access checking against every caller, on every call.
1.278 + * <p>
1.279 + * All access checks start from a {@code Lookup} object, which
1.280 + * compares its recorded lookup class against all requests to
1.281 + * create method handles.
1.282 + * A single {@code Lookup} object can be used to create any number
1.283 + * of access-checked method handles, all checked against a single
1.284 + * lookup class.
1.285 + * <p>
1.286 + * A {@code Lookup} object can be shared with other trusted code,
1.287 + * such as a metaobject protocol.
1.288 + * A shared {@code Lookup} object delegates the capability
1.289 + * to create method handles on private members of the lookup class.
1.290 + * Even if privileged code uses the {@code Lookup} object,
1.291 + * the access checking is confined to the privileges of the
1.292 + * original lookup class.
1.293 + * <p>
1.294 + * A lookup can fail, because
1.295 + * the containing class is not accessible to the lookup class, or
1.296 + * because the desired class member is missing, or because the
1.297 + * desired class member is not accessible to the lookup class, or
1.298 + * because the lookup object is not trusted enough to access the member.
1.299 + * In any of these cases, a {@code ReflectiveOperationException} will be
1.300 + * thrown from the attempted lookup. The exact class will be one of
1.301 + * the following:
1.302 + * <ul>
1.303 + * <li>NoSuchMethodException — if a method is requested but does not exist
1.304 + * <li>NoSuchFieldException — if a field is requested but does not exist
1.305 + * <li>IllegalAccessException — if the member exists but an access check fails
1.306 + * </ul>
1.307 + * <p>
1.308 + * In general, the conditions under which a method handle may be
1.309 + * looked up for a method {@code M} are no more restrictive than the conditions
1.310 + * under which the lookup class could have compiled, verified, and resolved a call to {@code M}.
1.311 + * Where the JVM would raise exceptions like {@code NoSuchMethodError},
1.312 + * a method handle lookup will generally raise a corresponding
1.313 + * checked exception, such as {@code NoSuchMethodException}.
1.314 + * And the effect of invoking the method handle resulting from the lookup
1.315 + * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a>
1.316 + * to executing the compiled, verified, and resolved call to {@code M}.
1.317 + * The same point is true of fields and constructors.
1.318 + * <p style="font-size:smaller;">
1.319 + * <em>Discussion:</em>
1.320 + * Access checks only apply to named and reflected methods,
1.321 + * constructors, and fields.
1.322 + * Other method handle creation methods, such as
1.323 + * {@link MethodHandle#asType MethodHandle.asType},
1.324 + * do not require any access checks, and are used
1.325 + * independently of any {@code Lookup} object.
1.326 + * <p>
1.327 + * If the desired member is {@code protected}, the usual JVM rules apply,
1.328 + * including the requirement that the lookup class must be either be in the
1.329 + * same package as the desired member, or must inherit that member.
1.330 + * (See the Java Virtual Machine Specification, sections 4.9.2, 5.4.3.5, and 6.4.)
1.331 + * In addition, if the desired member is a non-static field or method
1.332 + * in a different package, the resulting method handle may only be applied
1.333 + * to objects of the lookup class or one of its subclasses.
1.334 + * This requirement is enforced by narrowing the type of the leading
1.335 + * {@code this} parameter from {@code C}
1.336 + * (which will necessarily be a superclass of the lookup class)
1.337 + * to the lookup class itself.
1.338 + * <p>
1.339 + * The JVM imposes a similar requirement on {@code invokespecial} instruction,
1.340 + * that the receiver argument must match both the resolved method <em>and</em>
1.341 + * the current class. Again, this requirement is enforced by narrowing the
1.342 + * type of the leading parameter to the resulting method handle.
1.343 + * (See the Java Virtual Machine Specification, section 4.10.1.9.)
1.344 + * <p>
1.345 + * The JVM represents constructors and static initializer blocks as internal methods
1.346 + * with special names ({@code "<init>"} and {@code "<clinit>"}).
1.347 + * The internal syntax of invocation instructions allows them to refer to such internal
1.348 + * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
1.349 + * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
1.350 + * <p>
1.351 + * In some cases, access between nested classes is obtained by the Java compiler by creating
1.352 + * an wrapper method to access a private method of another class
1.353 + * in the same top-level declaration.
1.354 + * For example, a nested class {@code C.D}
1.355 + * can access private members within other related classes such as
1.356 + * {@code C}, {@code C.D.E}, or {@code C.B},
1.357 + * but the Java compiler may need to generate wrapper methods in
1.358 + * those related classes. In such cases, a {@code Lookup} object on
1.359 + * {@code C.E} would be unable to those private members.
1.360 + * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
1.361 + * which can transform a lookup on {@code C.E} into one on any of those other
1.362 + * classes, without special elevation of privilege.
1.363 + * <p>
1.364 + * The accesses permitted to a given lookup object may be limited,
1.365 + * according to its set of {@link #lookupModes lookupModes},
1.366 + * to a subset of members normally accessible to the lookup class.
1.367 + * For example, the {@link MethodHandles#publicLookup publicLookup}
1.368 + * method produces a lookup object which is only allowed to access
1.369 + * public members in public classes.
1.370 + * The caller sensitive method {@link MethodHandles#lookup lookup}
1.371 + * produces a lookup object with full capabilities relative to
1.372 + * its caller class, to emulate all supported bytecode behaviors.
1.373 + * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object
1.374 + * with fewer access modes than the original lookup object.
1.375 + *
1.376 + * <p style="font-size:smaller;">
1.377 + * <a name="privacc"></a>
1.378 + * <em>Discussion of private access:</em>
1.379 + * We say that a lookup has <em>private access</em>
1.380 + * if its {@linkplain #lookupModes lookup modes}
1.381 + * include the possibility of accessing {@code private} members.
1.382 + * As documented in the relevant methods elsewhere,
1.383 + * only lookups with private access possess the following capabilities:
1.384 + * <ul style="font-size:smaller;">
1.385 + * <li>access private fields, methods, and constructors of the lookup class
1.386 + * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
1.387 + * such as {@code Class.forName}
1.388 + * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
1.389 + * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
1.390 + * for classes accessible to the lookup class
1.391 + * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
1.392 + * within the same package member
1.393 + * </ul>
1.394 + * <p style="font-size:smaller;">
1.395 + * Each of these permissions is a consequence of the fact that a lookup object
1.396 + * with private access can be securely traced back to an originating class,
1.397 + * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
1.398 + * can be reliably determined and emulated by method handles.
1.399 + *
1.400 + * <h1><a name="secmgr"></a>Security manager interactions</h1>
1.401 + * Although bytecode instructions can only refer to classes in
1.402 + * a related class loader, this API can search for methods in any
1.403 + * class, as long as a reference to its {@code Class} object is
1.404 + * available. Such cross-loader references are also possible with the
1.405 + * Core Reflection API, and are impossible to bytecode instructions
1.406 + * such as {@code invokestatic} or {@code getfield}.
1.407 + * There is a {@linkplain java.lang.SecurityManager security manager API}
1.408 + * to allow applications to check such cross-loader references.
1.409 + * These checks apply to both the {@code MethodHandles.Lookup} API
1.410 + * and the Core Reflection API
1.411 + * (as found on {@link java.lang.Class Class}).
1.412 + * <p>
1.413 + * If a security manager is present, member lookups are subject to
1.414 + * additional checks.
1.415 + * From one to three calls are made to the security manager.
1.416 + * Any of these calls can refuse access by throwing a
1.417 + * {@link java.lang.SecurityException SecurityException}.
1.418 + * Define {@code smgr} as the security manager,
1.419 + * {@code lookc} as the lookup class of the current lookup object,
1.420 + * {@code refc} as the containing class in which the member
1.421 + * is being sought, and {@code defc} as the class in which the
1.422 + * member is actually defined.
1.423 + * The value {@code lookc} is defined as <em>not present</em>
1.424 + * if the current lookup object does not have
1.425 + * <a href="MethodHandles.Lookup.html#privacc">private access</a>.
1.426 + * The calls are made according to the following rules:
1.427 + * <ul>
1.428 + * <li><b>Step 1:</b>
1.429 + * If {@code lookc} is not present, or if its class loader is not
1.430 + * the same as or an ancestor of the class loader of {@code refc},
1.431 + * then {@link SecurityManager#checkPackageAccess
1.432 + * smgr.checkPackageAccess(refcPkg)} is called,
1.433 + * where {@code refcPkg} is the package of {@code refc}.
1.434 + * <li><b>Step 2:</b>
1.435 + * If the retrieved member is not public and
1.436 + * {@code lookc} is not present, then
1.437 + * {@link SecurityManager#checkPermission smgr.checkPermission}
1.438 + * with {@code RuntimePermission("accessDeclaredMembers")} is called.
1.439 + * <li><b>Step 3:</b>
1.440 + * If the retrieved member is not public,
1.441 + * and if {@code lookc} is not present,
1.442 + * and if {@code defc} and {@code refc} are different,
1.443 + * then {@link SecurityManager#checkPackageAccess
1.444 + * smgr.checkPackageAccess(defcPkg)} is called,
1.445 + * where {@code defcPkg} is the package of {@code defc}.
1.446 + * </ul>
1.447 + * Security checks are performed after other access checks have passed.
1.448 + * Therefore, the above rules presuppose a member that is public,
1.449 + * or else that is being accessed from a lookup class that has
1.450 + * rights to access the member.
1.451 + *
1.452 + * <h1><a name="callsens"></a>Caller sensitive methods</h1>
1.453 + * A small number of Java methods have a special property called caller sensitivity.
1.454 + * A <em>caller-sensitive</em> method can behave differently depending on the
1.455 + * identity of its immediate caller.
1.456 + * <p>
1.457 + * If a method handle for a caller-sensitive method is requested,
1.458 + * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
1.459 + * but they take account of the lookup class in a special way.
1.460 + * The resulting method handle behaves as if it were called
1.461 + * from an instruction contained in the lookup class,
1.462 + * so that the caller-sensitive method detects the lookup class.
1.463 + * (By contrast, the invoker of the method handle is disregarded.)
1.464 + * Thus, in the case of caller-sensitive methods,
1.465 + * different lookup classes may give rise to
1.466 + * differently behaving method handles.
1.467 + * <p>
1.468 + * In cases where the lookup object is
1.469 + * {@link MethodHandles#publicLookup() publicLookup()},
1.470 + * or some other lookup object without
1.471 + * <a href="MethodHandles.Lookup.html#privacc">private access</a>,
1.472 + * the lookup class is disregarded.
1.473 + * In such cases, no caller-sensitive method handle can be created,
1.474 + * access is forbidden, and the lookup fails with an
1.475 + * {@code IllegalAccessException}.
1.476 + * <p style="font-size:smaller;">
1.477 + * <em>Discussion:</em>
1.478 + * For example, the caller-sensitive method
1.479 + * {@link java.lang.Class#forName(String) Class.forName(x)}
1.480 + * can return varying classes or throw varying exceptions,
1.481 + * depending on the class loader of the class that calls it.
1.482 + * A public lookup of {@code Class.forName} will fail, because
1.483 + * there is no reasonable way to determine its bytecode behavior.
1.484 + * <p style="font-size:smaller;">
1.485 + * If an application caches method handles for broad sharing,
1.486 + * it should use {@code publicLookup()} to create them.
1.487 + * If there is a lookup of {@code Class.forName}, it will fail,
1.488 + * and the application must take appropriate action in that case.
1.489 + * It may be that a later lookup, perhaps during the invocation of a
1.490 + * bootstrap method, can incorporate the specific identity
1.491 + * of the caller, making the method accessible.
1.492 + * <p style="font-size:smaller;">
1.493 + * The function {@code MethodHandles.lookup} is caller sensitive
1.494 + * so that there can be a secure foundation for lookups.
1.495 + * Nearly all other methods in the JSR 292 API rely on lookup
1.496 + * objects to check access requests.
1.497 + */
1.498 + public static final
1.499 + class Lookup {
1.500 + /** The class on behalf of whom the lookup is being performed. */
1.501 + private final Class<?> lookupClass;
1.502 +
1.503 + /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
1.504 + private final int allowedModes;
1.505 +
1.506 + /** A single-bit mask representing {@code public} access,
1.507 + * which may contribute to the result of {@link #lookupModes lookupModes}.
1.508 + * The value, {@code 0x01}, happens to be the same as the value of the
1.509 + * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
1.510 + */
1.511 + public static final int PUBLIC = Modifier.PUBLIC;
1.512 +
1.513 + /** A single-bit mask representing {@code private} access,
1.514 + * which may contribute to the result of {@link #lookupModes lookupModes}.
1.515 + * The value, {@code 0x02}, happens to be the same as the value of the
1.516 + * {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
1.517 + */
1.518 + public static final int PRIVATE = Modifier.PRIVATE;
1.519 +
1.520 + /** A single-bit mask representing {@code protected} access,
1.521 + * which may contribute to the result of {@link #lookupModes lookupModes}.
1.522 + * The value, {@code 0x04}, happens to be the same as the value of the
1.523 + * {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
1.524 + */
1.525 + public static final int PROTECTED = Modifier.PROTECTED;
1.526 +
1.527 + /** A single-bit mask representing {@code package} access (default access),
1.528 + * which may contribute to the result of {@link #lookupModes lookupModes}.
1.529 + * The value is {@code 0x08}, which does not correspond meaningfully to
1.530 + * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
1.531 + */
1.532 + public static final int PACKAGE = Modifier.STATIC;
1.533 +
1.534 + private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
1.535 + private static final int TRUSTED = -1;
1.536 +
1.537 + private static int fixmods(int mods) {
1.538 + mods &= (ALL_MODES - PACKAGE);
1.539 + return (mods != 0) ? mods : PACKAGE;
1.540 + }
1.541 +
1.542 + /** Tells which class is performing the lookup. It is this class against
1.543 + * which checks are performed for visibility and access permissions.
1.544 + * <p>
1.545 + * The class implies a maximum level of access permission,
1.546 + * but the permissions may be additionally limited by the bitmask
1.547 + * {@link #lookupModes lookupModes}, which controls whether non-public members
1.548 + * can be accessed.
1.549 + * @return the lookup class, on behalf of which this lookup object finds members
1.550 + */
1.551 + public Class<?> lookupClass() {
1.552 + return lookupClass;
1.553 + }
1.554 +
1.555 + // This is just for calling out to MethodHandleImpl.
1.556 + private Class<?> lookupClassOrNull() {
1.557 + return (allowedModes == TRUSTED) ? null : lookupClass;
1.558 + }
1.559 +
1.560 + /** Tells which access-protection classes of members this lookup object can produce.
1.561 + * The result is a bit-mask of the bits
1.562 + * {@linkplain #PUBLIC PUBLIC (0x01)},
1.563 + * {@linkplain #PRIVATE PRIVATE (0x02)},
1.564 + * {@linkplain #PROTECTED PROTECTED (0x04)},
1.565 + * and {@linkplain #PACKAGE PACKAGE (0x08)}.
1.566 + * <p>
1.567 + * A freshly-created lookup object
1.568 + * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
1.569 + * has all possible bits set, since the caller class can access all its own members.
1.570 + * A lookup object on a new lookup class
1.571 + * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
1.572 + * may have some mode bits set to zero.
1.573 + * The purpose of this is to restrict access via the new lookup object,
1.574 + * so that it can access only names which can be reached by the original
1.575 + * lookup object, and also by the new lookup class.
1.576 + * @return the lookup modes, which limit the kinds of access performed by this lookup object
1.577 + */
1.578 + public int lookupModes() {
1.579 + return allowedModes & ALL_MODES;
1.580 + }
1.581 +
1.582 + /** Embody the current class (the lookupClass) as a lookup class
1.583 + * for method handle creation.
1.584 + * Must be called by from a method in this package,
1.585 + * which in turn is called by a method not in this package.
1.586 + */
1.587 + Lookup(Class<?> lookupClass) {
1.588 + this(lookupClass, ALL_MODES);
1.589 + // make sure we haven't accidentally picked up a privileged class:
1.590 + }
1.591 +
1.592 + private Lookup(Class<?> lookupClass, int allowedModes) {
1.593 + this.lookupClass = lookupClass;
1.594 + this.allowedModes = allowedModes;
1.595 + }
1.596 +
1.597 + /**
1.598 + * Creates a lookup on the specified new lookup class.
1.599 + * The resulting object will report the specified
1.600 + * class as its own {@link #lookupClass lookupClass}.
1.601 + * <p>
1.602 + * However, the resulting {@code Lookup} object is guaranteed
1.603 + * to have no more access capabilities than the original.
1.604 + * In particular, access capabilities can be lost as follows:<ul>
1.605 + * <li>If the new lookup class differs from the old one,
1.606 + * protected members will not be accessible by virtue of inheritance.
1.607 + * (Protected members may continue to be accessible because of package sharing.)
1.608 + * <li>If the new lookup class is in a different package
1.609 + * than the old one, protected and default (package) members will not be accessible.
1.610 + * <li>If the new lookup class is not within the same package member
1.611 + * as the old one, private members will not be accessible.
1.612 + * <li>If the new lookup class is not accessible to the old lookup class,
1.613 + * then no members, not even public members, will be accessible.
1.614 + * (In all other cases, public members will continue to be accessible.)
1.615 + * </ul>
1.616 + *
1.617 + * @param requestedLookupClass the desired lookup class for the new lookup object
1.618 + * @return a lookup object which reports the desired lookup class
1.619 + * @throws NullPointerException if the argument is null
1.620 + */
1.621 + public Lookup in(Class<?> requestedLookupClass) {
1.622 + throw new IllegalStateException();
1.623 + }
1.624 +
1.625 + /** Version of lookup which is trusted minimally.
1.626 + * It can only be used to create method handles to
1.627 + * publicly accessible members.
1.628 + */
1.629 + static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
1.630 +
1.631 + /** Package-private version of lookup which is trusted. */
1.632 + static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
1.633 +
1.634 + /**
1.635 + * Displays the name of the class from which lookups are to be made.
1.636 + * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
1.637 + * If there are restrictions on the access permitted to this lookup,
1.638 + * this is indicated by adding a suffix to the class name, consisting
1.639 + * of a slash and a keyword. The keyword represents the strongest
1.640 + * allowed access, and is chosen as follows:
1.641 + * <ul>
1.642 + * <li>If no access is allowed, the suffix is "/noaccess".
1.643 + * <li>If only public access is allowed, the suffix is "/public".
1.644 + * <li>If only public and package access are allowed, the suffix is "/package".
1.645 + * <li>If only public, package, and private access are allowed, the suffix is "/private".
1.646 + * </ul>
1.647 + * If none of the above cases apply, it is the case that full
1.648 + * access (public, package, private, and protected) is allowed.
1.649 + * In this case, no suffix is added.
1.650 + * This is true only of an object obtained originally from
1.651 + * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
1.652 + * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
1.653 + * always have restricted access, and will display a suffix.
1.654 + * <p>
1.655 + * (It may seem strange that protected access should be
1.656 + * stronger than private access. Viewed independently from
1.657 + * package access, protected access is the first to be lost,
1.658 + * because it requires a direct subclass relationship between
1.659 + * caller and callee.)
1.660 + * @see #in
1.661 + */
1.662 + @Override
1.663 + public String toString() {
1.664 + String cname = lookupClass.getName();
1.665 + switch (allowedModes) {
1.666 + case 0: // no privileges
1.667 + return cname + "/noaccess";
1.668 + case PUBLIC:
1.669 + return cname + "/public";
1.670 + case PUBLIC|PACKAGE:
1.671 + return cname + "/package";
1.672 + case ALL_MODES & ~PROTECTED:
1.673 + return cname + "/private";
1.674 + case ALL_MODES:
1.675 + return cname;
1.676 + case TRUSTED:
1.677 + return "/trusted"; // internal only; not exported
1.678 + default: // Should not happen, but it's a bitfield...
1.679 + cname = cname + "/" + Integer.toHexString(allowedModes);
1.680 + assert(false) : cname;
1.681 + return cname;
1.682 + }
1.683 + }
1.684 +
1.685 + /**
1.686 + * Produces a method handle for a static method.
1.687 + * The type of the method handle will be that of the method.
1.688 + * (Since static methods do not take receivers, there is no
1.689 + * additional receiver argument inserted into the method handle type,
1.690 + * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
1.691 + * The method and all its argument types must be accessible to the lookup object.
1.692 + * <p>
1.693 + * The returned method handle will have
1.694 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1.695 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
1.696 + * <p>
1.697 + * If the returned method handle is invoked, the method's class will
1.698 + * be initialized, if it has not already been initialized.
1.699 + * <p><b>Example:</b>
1.700 + * <blockquote><pre>{@code
1.701 +import static java.lang.invoke.MethodHandles.*;
1.702 +import static java.lang.invoke.MethodType.*;
1.703 +...
1.704 +MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
1.705 + "asList", methodType(List.class, Object[].class));
1.706 +assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
1.707 + * }</pre></blockquote>
1.708 + * @param refc the class from which the method is accessed
1.709 + * @param name the name of the method
1.710 + * @param type the type of the method
1.711 + * @return the desired method handle
1.712 + * @throws NoSuchMethodException if the method does not exist
1.713 + * @throws IllegalAccessException if access checking fails,
1.714 + * or if the method is not {@code static},
1.715 + * or if the method's variable arity modifier bit
1.716 + * is set and {@code asVarargsCollector} fails
1.717 + * @exception SecurityException if a security manager is present and it
1.718 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.719 + * @throws NullPointerException if any argument is null
1.720 + */
1.721 + public
1.722 + MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1.723 + throw new IllegalStateException();
1.724 + }
1.725 +
1.726 + /**
1.727 + * Produces a method handle for a virtual method.
1.728 + * The type of the method handle will be that of the method,
1.729 + * with the receiver type (usually {@code refc}) prepended.
1.730 + * The method and all its argument types must be accessible to the lookup object.
1.731 + * <p>
1.732 + * When called, the handle will treat the first argument as a receiver
1.733 + * and dispatch on the receiver's type to determine which method
1.734 + * implementation to enter.
1.735 + * (The dispatching action is identical with that performed by an
1.736 + * {@code invokevirtual} or {@code invokeinterface} instruction.)
1.737 + * <p>
1.738 + * The first argument will be of type {@code refc} if the lookup
1.739 + * class has full privileges to access the member. Otherwise
1.740 + * the member must be {@code protected} and the first argument
1.741 + * will be restricted in type to the lookup class.
1.742 + * <p>
1.743 + * The returned method handle will have
1.744 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1.745 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
1.746 + * <p>
1.747 + * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual}
1.748 + * instructions and method handles produced by {@code findVirtual},
1.749 + * if the class is {@code MethodHandle} and the name string is
1.750 + * {@code invokeExact} or {@code invoke}, the resulting
1.751 + * method handle is equivalent to one produced by
1.752 + * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
1.753 + * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
1.754 + * with the same {@code type} argument.
1.755 + *
1.756 + * <b>Example:</b>
1.757 + * <blockquote><pre>{@code
1.758 +import static java.lang.invoke.MethodHandles.*;
1.759 +import static java.lang.invoke.MethodType.*;
1.760 +...
1.761 +MethodHandle MH_concat = publicLookup().findVirtual(String.class,
1.762 + "concat", methodType(String.class, String.class));
1.763 +MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
1.764 + "hashCode", methodType(int.class));
1.765 +MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
1.766 + "hashCode", methodType(int.class));
1.767 +assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
1.768 +assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
1.769 +assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
1.770 +// interface method:
1.771 +MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
1.772 + "subSequence", methodType(CharSequence.class, int.class, int.class));
1.773 +assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
1.774 +// constructor "internal method" must be accessed differently:
1.775 +MethodType MT_newString = methodType(void.class); //()V for new String()
1.776 +try { assertEquals("impossible", lookup()
1.777 + .findVirtual(String.class, "<init>", MT_newString));
1.778 + } catch (NoSuchMethodException ex) { } // OK
1.779 +MethodHandle MH_newString = publicLookup()
1.780 + .findConstructor(String.class, MT_newString);
1.781 +assertEquals("", (String) MH_newString.invokeExact());
1.782 + * }</pre></blockquote>
1.783 + *
1.784 + * @param refc the class or interface from which the method is accessed
1.785 + * @param name the name of the method
1.786 + * @param type the type of the method, with the receiver argument omitted
1.787 + * @return the desired method handle
1.788 + * @throws NoSuchMethodException if the method does not exist
1.789 + * @throws IllegalAccessException if access checking fails,
1.790 + * or if the method is {@code static}
1.791 + * or if the method's variable arity modifier bit
1.792 + * is set and {@code asVarargsCollector} fails
1.793 + * @exception SecurityException if a security manager is present and it
1.794 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.795 + * @throws NullPointerException if any argument is null
1.796 + */
1.797 + public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1.798 + throw new IllegalStateException();
1.799 + }
1.800 +
1.801 + /**
1.802 + * Produces a method handle which creates an object and initializes it, using
1.803 + * the constructor of the specified type.
1.804 + * The parameter types of the method handle will be those of the constructor,
1.805 + * while the return type will be a reference to the constructor's class.
1.806 + * The constructor and all its argument types must be accessible to the lookup object.
1.807 + * <p>
1.808 + * The requested type must have a return type of {@code void}.
1.809 + * (This is consistent with the JVM's treatment of constructor type descriptors.)
1.810 + * <p>
1.811 + * The returned method handle will have
1.812 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1.813 + * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
1.814 + * <p>
1.815 + * If the returned method handle is invoked, the constructor's class will
1.816 + * be initialized, if it has not already been initialized.
1.817 + * <p><b>Example:</b>
1.818 + * <blockquote><pre>{@code
1.819 +import static java.lang.invoke.MethodHandles.*;
1.820 +import static java.lang.invoke.MethodType.*;
1.821 +...
1.822 +MethodHandle MH_newArrayList = publicLookup().findConstructor(
1.823 + ArrayList.class, methodType(void.class, Collection.class));
1.824 +Collection orig = Arrays.asList("x", "y");
1.825 +Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
1.826 +assert(orig != copy);
1.827 +assertEquals(orig, copy);
1.828 +// a variable-arity constructor:
1.829 +MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
1.830 + ProcessBuilder.class, methodType(void.class, String[].class));
1.831 +ProcessBuilder pb = (ProcessBuilder)
1.832 + MH_newProcessBuilder.invoke("x", "y", "z");
1.833 +assertEquals("[x, y, z]", pb.command().toString());
1.834 + * }</pre></blockquote>
1.835 + * @param refc the class or interface from which the method is accessed
1.836 + * @param type the type of the method, with the receiver argument omitted, and a void return type
1.837 + * @return the desired method handle
1.838 + * @throws NoSuchMethodException if the constructor does not exist
1.839 + * @throws IllegalAccessException if access checking fails
1.840 + * or if the method's variable arity modifier bit
1.841 + * is set and {@code asVarargsCollector} fails
1.842 + * @exception SecurityException if a security manager is present and it
1.843 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.844 + * @throws NullPointerException if any argument is null
1.845 + */
1.846 + public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1.847 + throw new IllegalStateException();
1.848 + }
1.849 +
1.850 + /**
1.851 + * Produces an early-bound method handle for a virtual method.
1.852 + * It will bypass checks for overriding methods on the receiver,
1.853 + * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
1.854 + * instruction from within the explicitly specified {@code specialCaller}.
1.855 + * The type of the method handle will be that of the method,
1.856 + * with a suitably restricted receiver type prepended.
1.857 + * (The receiver type will be {@code specialCaller} or a subtype.)
1.858 + * The method and all its argument types must be accessible
1.859 + * to the lookup object.
1.860 + * <p>
1.861 + * Before method resolution,
1.862 + * if the explicitly specified caller class is not identical with the
1.863 + * lookup class, or if this lookup object does not have
1.864 + * <a href="MethodHandles.Lookup.html#privacc">private access</a>
1.865 + * privileges, the access fails.
1.866 + * <p>
1.867 + * The returned method handle will have
1.868 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1.869 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
1.870 + * <p style="font-size:smaller;">
1.871 + * <em>(Note: JVM internal methods named {@code "<init>"} are not visible to this API,
1.872 + * even though the {@code invokespecial} instruction can refer to them
1.873 + * in special circumstances. Use {@link #findConstructor findConstructor}
1.874 + * to access instance initialization methods in a safe manner.)</em>
1.875 + * <p><b>Example:</b>
1.876 + * <blockquote><pre>{@code
1.877 +import static java.lang.invoke.MethodHandles.*;
1.878 +import static java.lang.invoke.MethodType.*;
1.879 +...
1.880 +static class Listie extends ArrayList {
1.881 + public String toString() { return "[wee Listie]"; }
1.882 + static Lookup lookup() { return MethodHandles.lookup(); }
1.883 +}
1.884 +...
1.885 +// no access to constructor via invokeSpecial:
1.886 +MethodHandle MH_newListie = Listie.lookup()
1.887 + .findConstructor(Listie.class, methodType(void.class));
1.888 +Listie l = (Listie) MH_newListie.invokeExact();
1.889 +try { assertEquals("impossible", Listie.lookup().findSpecial(
1.890 + Listie.class, "<init>", methodType(void.class), Listie.class));
1.891 + } catch (NoSuchMethodException ex) { } // OK
1.892 +// access to super and self methods via invokeSpecial:
1.893 +MethodHandle MH_super = Listie.lookup().findSpecial(
1.894 + ArrayList.class, "toString" , methodType(String.class), Listie.class);
1.895 +MethodHandle MH_this = Listie.lookup().findSpecial(
1.896 + Listie.class, "toString" , methodType(String.class), Listie.class);
1.897 +MethodHandle MH_duper = Listie.lookup().findSpecial(
1.898 + Object.class, "toString" , methodType(String.class), Listie.class);
1.899 +assertEquals("[]", (String) MH_super.invokeExact(l));
1.900 +assertEquals(""+l, (String) MH_this.invokeExact(l));
1.901 +assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
1.902 +try { assertEquals("inaccessible", Listie.lookup().findSpecial(
1.903 + String.class, "toString", methodType(String.class), Listie.class));
1.904 + } catch (IllegalAccessException ex) { } // OK
1.905 +Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
1.906 +assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
1.907 + * }</pre></blockquote>
1.908 + *
1.909 + * @param refc the class or interface from which the method is accessed
1.910 + * @param name the name of the method (which must not be "<init>")
1.911 + * @param type the type of the method, with the receiver argument omitted
1.912 + * @param specialCaller the proposed calling class to perform the {@code invokespecial}
1.913 + * @return the desired method handle
1.914 + * @throws NoSuchMethodException if the method does not exist
1.915 + * @throws IllegalAccessException if access checking fails
1.916 + * or if the method's variable arity modifier bit
1.917 + * is set and {@code asVarargsCollector} fails
1.918 + * @exception SecurityException if a security manager is present and it
1.919 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.920 + * @throws NullPointerException if any argument is null
1.921 + */
1.922 + public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
1.923 + Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
1.924 + throw new IllegalStateException();
1.925 + }
1.926 +
1.927 + /**
1.928 + * Produces a method handle giving read access to a non-static field.
1.929 + * The type of the method handle will have a return type of the field's
1.930 + * value type.
1.931 + * The method handle's single argument will be the instance containing
1.932 + * the field.
1.933 + * Access checking is performed immediately on behalf of the lookup class.
1.934 + * @param refc the class or interface from which the method is accessed
1.935 + * @param name the field's name
1.936 + * @param type the field's type
1.937 + * @return a method handle which can load values from the field
1.938 + * @throws NoSuchFieldException if the field does not exist
1.939 + * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
1.940 + * @exception SecurityException if a security manager is present and it
1.941 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.942 + * @throws NullPointerException if any argument is null
1.943 + */
1.944 + public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
1.945 + throw new IllegalStateException();
1.946 + }
1.947 +
1.948 + /**
1.949 + * Produces a method handle giving write access to a non-static field.
1.950 + * The type of the method handle will have a void return type.
1.951 + * The method handle will take two arguments, the instance containing
1.952 + * the field, and the value to be stored.
1.953 + * The second argument will be of the field's value type.
1.954 + * Access checking is performed immediately on behalf of the lookup class.
1.955 + * @param refc the class or interface from which the method is accessed
1.956 + * @param name the field's name
1.957 + * @param type the field's type
1.958 + * @return a method handle which can store values into the field
1.959 + * @throws NoSuchFieldException if the field does not exist
1.960 + * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
1.961 + * @exception SecurityException if a security manager is present and it
1.962 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.963 + * @throws NullPointerException if any argument is null
1.964 + */
1.965 + public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
1.966 + throw new IllegalStateException();
1.967 + }
1.968 +
1.969 + /**
1.970 + * Produces a method handle giving read access to a static field.
1.971 + * The type of the method handle will have a return type of the field's
1.972 + * value type.
1.973 + * The method handle will take no arguments.
1.974 + * Access checking is performed immediately on behalf of the lookup class.
1.975 + * <p>
1.976 + * If the returned method handle is invoked, the field's class will
1.977 + * be initialized, if it has not already been initialized.
1.978 + * @param refc the class or interface from which the method is accessed
1.979 + * @param name the field's name
1.980 + * @param type the field's type
1.981 + * @return a method handle which can load values from the field
1.982 + * @throws NoSuchFieldException if the field does not exist
1.983 + * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
1.984 + * @exception SecurityException if a security manager is present and it
1.985 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.986 + * @throws NullPointerException if any argument is null
1.987 + */
1.988 + public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
1.989 + throw new IllegalStateException();
1.990 + }
1.991 +
1.992 + /**
1.993 + * Produces a method handle giving write access to a static field.
1.994 + * The type of the method handle will have a void return type.
1.995 + * The method handle will take a single
1.996 + * argument, of the field's value type, the value to be stored.
1.997 + * Access checking is performed immediately on behalf of the lookup class.
1.998 + * <p>
1.999 + * If the returned method handle is invoked, the field's class will
1.1000 + * be initialized, if it has not already been initialized.
1.1001 + * @param refc the class or interface from which the method is accessed
1.1002 + * @param name the field's name
1.1003 + * @param type the field's type
1.1004 + * @return a method handle which can store values into the field
1.1005 + * @throws NoSuchFieldException if the field does not exist
1.1006 + * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
1.1007 + * @exception SecurityException if a security manager is present and it
1.1008 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.1009 + * @throws NullPointerException if any argument is null
1.1010 + */
1.1011 + public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
1.1012 + throw new IllegalStateException();
1.1013 + }
1.1014 +
1.1015 + /**
1.1016 + * Produces an early-bound method handle for a non-static method.
1.1017 + * The receiver must have a supertype {@code defc} in which a method
1.1018 + * of the given name and type is accessible to the lookup class.
1.1019 + * The method and all its argument types must be accessible to the lookup object.
1.1020 + * The type of the method handle will be that of the method,
1.1021 + * without any insertion of an additional receiver parameter.
1.1022 + * The given receiver will be bound into the method handle,
1.1023 + * so that every call to the method handle will invoke the
1.1024 + * requested method on the given receiver.
1.1025 + * <p>
1.1026 + * The returned method handle will have
1.1027 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1.1028 + * the method's variable arity modifier bit ({@code 0x0080}) is set
1.1029 + * <em>and</em> the trailing array argument is not the only argument.
1.1030 + * (If the trailing array argument is the only argument,
1.1031 + * the given receiver value will be bound to it.)
1.1032 + * <p>
1.1033 + * This is equivalent to the following code:
1.1034 + * <blockquote><pre>{@code
1.1035 +import static java.lang.invoke.MethodHandles.*;
1.1036 +import static java.lang.invoke.MethodType.*;
1.1037 +...
1.1038 +MethodHandle mh0 = lookup().findVirtual(defc, name, type);
1.1039 +MethodHandle mh1 = mh0.bindTo(receiver);
1.1040 +MethodType mt1 = mh1.type();
1.1041 +if (mh0.isVarargsCollector())
1.1042 + mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
1.1043 +return mh1;
1.1044 + * }</pre></blockquote>
1.1045 + * where {@code defc} is either {@code receiver.getClass()} or a super
1.1046 + * type of that class, in which the requested method is accessible
1.1047 + * to the lookup class.
1.1048 + * (Note that {@code bindTo} does not preserve variable arity.)
1.1049 + * @param receiver the object from which the method is accessed
1.1050 + * @param name the name of the method
1.1051 + * @param type the type of the method, with the receiver argument omitted
1.1052 + * @return the desired method handle
1.1053 + * @throws NoSuchMethodException if the method does not exist
1.1054 + * @throws IllegalAccessException if access checking fails
1.1055 + * or if the method's variable arity modifier bit
1.1056 + * is set and {@code asVarargsCollector} fails
1.1057 + * @exception SecurityException if a security manager is present and it
1.1058 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.1059 + * @throws NullPointerException if any argument is null
1.1060 + * @see MethodHandle#bindTo
1.1061 + * @see #findVirtual
1.1062 + */
1.1063 + public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1.1064 + throw new IllegalStateException();
1.1065 + }
1.1066 +
1.1067 + /**
1.1068 + * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
1.1069 + * to <i>m</i>, if the lookup class has permission.
1.1070 + * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
1.1071 + * If <i>m</i> is virtual, overriding is respected on every call.
1.1072 + * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
1.1073 + * The type of the method handle will be that of the method,
1.1074 + * with the receiver type prepended (but only if it is non-static).
1.1075 + * If the method's {@code accessible} flag is not set,
1.1076 + * access checking is performed immediately on behalf of the lookup class.
1.1077 + * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
1.1078 + * <p>
1.1079 + * The returned method handle will have
1.1080 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1.1081 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
1.1082 + * <p>
1.1083 + * If <i>m</i> is static, and
1.1084 + * if the returned method handle is invoked, the method's class will
1.1085 + * be initialized, if it has not already been initialized.
1.1086 + * @param m the reflected method
1.1087 + * @return a method handle which can invoke the reflected method
1.1088 + * @throws IllegalAccessException if access checking fails
1.1089 + * or if the method's variable arity modifier bit
1.1090 + * is set and {@code asVarargsCollector} fails
1.1091 + * @throws NullPointerException if the argument is null
1.1092 + */
1.1093 + public MethodHandle unreflect(Method m) throws IllegalAccessException {
1.1094 + throw new IllegalStateException();
1.1095 + }
1.1096 +
1.1097 + /**
1.1098 + * Produces a method handle for a reflected method.
1.1099 + * It will bypass checks for overriding methods on the receiver,
1.1100 + * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
1.1101 + * instruction from within the explicitly specified {@code specialCaller}.
1.1102 + * The type of the method handle will be that of the method,
1.1103 + * with a suitably restricted receiver type prepended.
1.1104 + * (The receiver type will be {@code specialCaller} or a subtype.)
1.1105 + * If the method's {@code accessible} flag is not set,
1.1106 + * access checking is performed immediately on behalf of the lookup class,
1.1107 + * as if {@code invokespecial} instruction were being linked.
1.1108 + * <p>
1.1109 + * Before method resolution,
1.1110 + * if the explicitly specified caller class is not identical with the
1.1111 + * lookup class, or if this lookup object does not have
1.1112 + * <a href="MethodHandles.Lookup.html#privacc">private access</a>
1.1113 + * privileges, the access fails.
1.1114 + * <p>
1.1115 + * The returned method handle will have
1.1116 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1.1117 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
1.1118 + * @param m the reflected method
1.1119 + * @param specialCaller the class nominally calling the method
1.1120 + * @return a method handle which can invoke the reflected method
1.1121 + * @throws IllegalAccessException if access checking fails
1.1122 + * or if the method's variable arity modifier bit
1.1123 + * is set and {@code asVarargsCollector} fails
1.1124 + * @throws NullPointerException if any argument is null
1.1125 + */
1.1126 + public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
1.1127 + throw new IllegalStateException();
1.1128 + }
1.1129 +
1.1130 + /**
1.1131 + * Produces a method handle for a reflected constructor.
1.1132 + * The type of the method handle will be that of the constructor,
1.1133 + * with the return type changed to the declaring class.
1.1134 + * The method handle will perform a {@code newInstance} operation,
1.1135 + * creating a new instance of the constructor's class on the
1.1136 + * arguments passed to the method handle.
1.1137 + * <p>
1.1138 + * If the constructor's {@code accessible} flag is not set,
1.1139 + * access checking is performed immediately on behalf of the lookup class.
1.1140 + * <p>
1.1141 + * The returned method handle will have
1.1142 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1.1143 + * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
1.1144 + * <p>
1.1145 + * If the returned method handle is invoked, the constructor's class will
1.1146 + * be initialized, if it has not already been initialized.
1.1147 + * @param c the reflected constructor
1.1148 + * @return a method handle which can invoke the reflected constructor
1.1149 + * @throws IllegalAccessException if access checking fails
1.1150 + * or if the method's variable arity modifier bit
1.1151 + * is set and {@code asVarargsCollector} fails
1.1152 + * @throws NullPointerException if the argument is null
1.1153 + */
1.1154 + public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
1.1155 + throw new IllegalStateException();
1.1156 + }
1.1157 +
1.1158 + /**
1.1159 + * Produces a method handle giving read access to a reflected field.
1.1160 + * The type of the method handle will have a return type of the field's
1.1161 + * value type.
1.1162 + * If the field is static, the method handle will take no arguments.
1.1163 + * Otherwise, its single argument will be the instance containing
1.1164 + * the field.
1.1165 + * If the field's {@code accessible} flag is not set,
1.1166 + * access checking is performed immediately on behalf of the lookup class.
1.1167 + * <p>
1.1168 + * If the field is static, and
1.1169 + * if the returned method handle is invoked, the field's class will
1.1170 + * be initialized, if it has not already been initialized.
1.1171 + * @param f the reflected field
1.1172 + * @return a method handle which can load values from the reflected field
1.1173 + * @throws IllegalAccessException if access checking fails
1.1174 + * @throws NullPointerException if the argument is null
1.1175 + */
1.1176 + public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
1.1177 + throw new IllegalStateException();
1.1178 + }
1.1179 +
1.1180 + /**
1.1181 + * Produces a method handle giving write access to a reflected field.
1.1182 + * The type of the method handle will have a void return type.
1.1183 + * If the field is static, the method handle will take a single
1.1184 + * argument, of the field's value type, the value to be stored.
1.1185 + * Otherwise, the two arguments will be the instance containing
1.1186 + * the field, and the value to be stored.
1.1187 + * If the field's {@code accessible} flag is not set,
1.1188 + * access checking is performed immediately on behalf of the lookup class.
1.1189 + * <p>
1.1190 + * If the field is static, and
1.1191 + * if the returned method handle is invoked, the field's class will
1.1192 + * be initialized, if it has not already been initialized.
1.1193 + * @param f the reflected field
1.1194 + * @return a method handle which can store values into the reflected field
1.1195 + * @throws IllegalAccessException if access checking fails
1.1196 + * @throws NullPointerException if the argument is null
1.1197 + */
1.1198 + public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
1.1199 + throw new IllegalStateException();
1.1200 + }
1.1201 +
1.1202 + /**
1.1203 + * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
1.1204 + * created by this lookup object or a similar one.
1.1205 + * Security and access checks are performed to ensure that this lookup object
1.1206 + * is capable of reproducing the target method handle.
1.1207 + * This means that the cracking may fail if target is a direct method handle
1.1208 + * but was created by an unrelated lookup object.
1.1209 + * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
1.1210 + * and was created by a lookup object for a different class.
1.1211 + * @param target a direct method handle to crack into symbolic reference components
1.1212 + * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
1.1213 + * @exception SecurityException if a security manager is present and it
1.1214 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1.1215 + * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
1.1216 + * @exception NullPointerException if the target is {@code null}
1.1217 + * @see MethodHandleInfo
1.1218 + * @since 1.8
1.1219 + */
1.1220 +// public MethodHandleInfo revealDirect(MethodHandle target) {
1.1221 +// throw new IllegalStateException();
1.1222 +// }
1.1223 + }
1.1224 +
1.1225 +}