rt/emul/compact/src/main/java/java/lang/invoke/MethodHandles.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 14 Sep 2014 19:27:44 +0200
changeset 1692 2f800fdc371e
permissions -rw-r--r--
Adding necessary fake classes to allow Javac to compile lamda expressions against our emulation library.
jaroslav@1692
     1
/*
jaroslav@1692
     2
 * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
jaroslav@1692
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@1692
     4
 *
jaroslav@1692
     5
 * This code is free software; you can redistribute it and/or modify it
jaroslav@1692
     6
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@1692
     7
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@1692
     8
 * particular file as subject to the "Classpath" exception as provided
jaroslav@1692
     9
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@1692
    10
 *
jaroslav@1692
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@1692
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@1692
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@1692
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@1692
    15
 * accompanied this code).
jaroslav@1692
    16
 *
jaroslav@1692
    17
 * You should have received a copy of the GNU General Public License version
jaroslav@1692
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@1692
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@1692
    20
 *
jaroslav@1692
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@1692
    22
 * or visit www.oracle.com if you need additional information or have any
jaroslav@1692
    23
 * questions.
jaroslav@1692
    24
 */
jaroslav@1692
    25
jaroslav@1692
    26
package java.lang.invoke;
jaroslav@1692
    27
jaroslav@1692
    28
import java.lang.reflect.*;
jaroslav@1692
    29
jaroslav@1692
    30
/**
jaroslav@1692
    31
 * This class consists exclusively of static methods that operate on or return
jaroslav@1692
    32
 * method handles. They fall into several categories:
jaroslav@1692
    33
 * <ul>
jaroslav@1692
    34
 * <li>Lookup methods which help create method handles for methods and fields.
jaroslav@1692
    35
 * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
jaroslav@1692
    36
 * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
jaroslav@1692
    37
 * </ul>
jaroslav@1692
    38
 * <p>
jaroslav@1692
    39
 * @author John Rose, JSR 292 EG
jaroslav@1692
    40
 * @since 1.7
jaroslav@1692
    41
 */
jaroslav@1692
    42
public class MethodHandles {
jaroslav@1692
    43
jaroslav@1692
    44
    private MethodHandles() { }  // do not instantiate
jaroslav@1692
    45
jaroslav@1692
    46
    //// Method handle creation from ordinary methods.
jaroslav@1692
    47
jaroslav@1692
    48
    /**
jaroslav@1692
    49
     * Returns a {@link Lookup lookup object} with
jaroslav@1692
    50
     * full capabilities to emulate all supported bytecode behaviors of the caller.
jaroslav@1692
    51
     * These capabilities include <a href="MethodHandles.Lookup.html#privacc">private access</a> to the caller.
jaroslav@1692
    52
     * Factory methods on the lookup object can create
jaroslav@1692
    53
     * <a href="MethodHandleInfo.html#directmh">direct method handles</a>
jaroslav@1692
    54
     * for any member that the caller has access to via bytecodes,
jaroslav@1692
    55
     * including protected and private fields and methods.
jaroslav@1692
    56
     * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
jaroslav@1692
    57
     * Do not store it in place where untrusted code can access it.
jaroslav@1692
    58
     * <p>
jaroslav@1692
    59
     * This method is caller sensitive, which means that it may return different
jaroslav@1692
    60
     * values to different callers.
jaroslav@1692
    61
     * <p>
jaroslav@1692
    62
     * For any given caller class {@code C}, the lookup object returned by this call
jaroslav@1692
    63
     * has equivalent capabilities to any lookup object
jaroslav@1692
    64
     * supplied by the JVM to the bootstrap method of an
jaroslav@1692
    65
     * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
jaroslav@1692
    66
     * executing in the same caller class {@code C}.
jaroslav@1692
    67
     * @return a lookup object for the caller of this method, with private access
jaroslav@1692
    68
     */
jaroslav@1692
    69
//    @CallerSensitive
jaroslav@1692
    70
    public static Lookup lookup() {
jaroslav@1692
    71
        throw new IllegalStateException("Implement me!");
jaroslav@1692
    72
//        return new Lookup(Reflection.getCallerClass());
jaroslav@1692
    73
    }
jaroslav@1692
    74
jaroslav@1692
    75
    /**
jaroslav@1692
    76
     * Returns a {@link Lookup lookup object} which is trusted minimally.
jaroslav@1692
    77
     * It can only be used to create method handles to
jaroslav@1692
    78
     * publicly accessible fields and methods.
jaroslav@1692
    79
     * <p>
jaroslav@1692
    80
     * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
jaroslav@1692
    81
     * of this lookup object will be {@link java.lang.Object}.
jaroslav@1692
    82
     *
jaroslav@1692
    83
     * <p style="font-size:smaller;">
jaroslav@1692
    84
     * <em>Discussion:</em>
jaroslav@1692
    85
     * The lookup class can be changed to any other class {@code C} using an expression of the form
jaroslav@1692
    86
     * {@link Lookup#in publicLookup().in(C.class)}.
jaroslav@1692
    87
     * Since all classes have equal access to public names,
jaroslav@1692
    88
     * such a change would confer no new access rights.
jaroslav@1692
    89
     * A public lookup object is always subject to
jaroslav@1692
    90
     * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
jaroslav@1692
    91
     * Also, it cannot access
jaroslav@1692
    92
     * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
jaroslav@1692
    93
     * @return a lookup object which is trusted minimally
jaroslav@1692
    94
     */
jaroslav@1692
    95
    public static Lookup publicLookup() {
jaroslav@1692
    96
        return Lookup.PUBLIC_LOOKUP;
jaroslav@1692
    97
    }
jaroslav@1692
    98
jaroslav@1692
    99
    /**
jaroslav@1692
   100
     * Performs an unchecked "crack" of a
jaroslav@1692
   101
     * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
jaroslav@1692
   102
     * The result is as if the user had obtained a lookup object capable enough
jaroslav@1692
   103
     * to crack the target method handle, called
jaroslav@1692
   104
     * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
jaroslav@1692
   105
     * on the target to obtain its symbolic reference, and then called
jaroslav@1692
   106
     * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
jaroslav@1692
   107
     * to resolve the symbolic reference to a member.
jaroslav@1692
   108
     * <p>
jaroslav@1692
   109
     * If there is a security manager, its {@code checkPermission} method
jaroslav@1692
   110
     * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
jaroslav@1692
   111
     * @param <T> the desired type of the result, either {@link Member} or a subtype
jaroslav@1692
   112
     * @param target a direct method handle to crack into symbolic reference components
jaroslav@1692
   113
     * @param expected a class object representing the desired result type {@code T}
jaroslav@1692
   114
     * @return a reference to the method, constructor, or field object
jaroslav@1692
   115
     * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
jaroslav@1692
   116
     * @exception NullPointerException if either argument is {@code null}
jaroslav@1692
   117
     * @exception IllegalArgumentException if the target is not a direct method handle
jaroslav@1692
   118
     * @exception ClassCastException if the member is not of the expected type
jaroslav@1692
   119
     * @since 1.8
jaroslav@1692
   120
     */
jaroslav@1692
   121
    public static <T extends Member> T
jaroslav@1692
   122
    reflectAs(Class<T> expected, MethodHandle target) {
jaroslav@1692
   123
        throw new IllegalStateException();
jaroslav@1692
   124
    }
jaroslav@1692
   125
    // Copied from AccessibleObject, as used by Method.setAccessible, etc.:
jaroslav@1692
   126
//    static final private java.security.Permission ACCESS_PERMISSION =
jaroslav@1692
   127
//        new ReflectPermission("suppressAccessChecks");
jaroslav@1692
   128
    
jaroslav@1692
   129
    static Lookup findFor(Class<?> clazz) {
jaroslav@1692
   130
        Object o = clazz;
jaroslav@1692
   131
        if (o instanceof Class) {
jaroslav@1692
   132
            return new Lookup(clazz, Lookup.ALL_MODES);
jaroslav@1692
   133
        }
jaroslav@1692
   134
        throw new IllegalArgumentException("Expecting class: " + o);
jaroslav@1692
   135
    }
jaroslav@1692
   136
jaroslav@1692
   137
    /**
jaroslav@1692
   138
     * A <em>lookup object</em> is a factory for creating method handles,
jaroslav@1692
   139
     * when the creation requires access checking.
jaroslav@1692
   140
     * Method handles do not perform
jaroslav@1692
   141
     * access checks when they are called, but rather when they are created.
jaroslav@1692
   142
     * Therefore, method handle access
jaroslav@1692
   143
     * restrictions must be enforced when a method handle is created.
jaroslav@1692
   144
     * The caller class against which those restrictions are enforced
jaroslav@1692
   145
     * is known as the {@linkplain #lookupClass lookup class}.
jaroslav@1692
   146
     * <p>
jaroslav@1692
   147
     * A lookup class which needs to create method handles will call
jaroslav@1692
   148
     * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
jaroslav@1692
   149
     * When the {@code Lookup} factory object is created, the identity of the lookup class is
jaroslav@1692
   150
     * determined, and securely stored in the {@code Lookup} object.
jaroslav@1692
   151
     * The lookup class (or its delegates) may then use factory methods
jaroslav@1692
   152
     * on the {@code Lookup} object to create method handles for access-checked members.
jaroslav@1692
   153
     * This includes all methods, constructors, and fields which are allowed to the lookup class,
jaroslav@1692
   154
     * even private ones.
jaroslav@1692
   155
     *
jaroslav@1692
   156
     * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
jaroslav@1692
   157
     * The factory methods on a {@code Lookup} object correspond to all major
jaroslav@1692
   158
     * use cases for methods, constructors, and fields.
jaroslav@1692
   159
     * Each method handle created by a factory method is the functional
jaroslav@1692
   160
     * equivalent of a particular <em>bytecode behavior</em>.
jaroslav@1692
   161
     * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.)
jaroslav@1692
   162
     * Here is a summary of the correspondence between these factory methods and
jaroslav@1692
   163
     * the behavior the resulting method handles:
jaroslav@1692
   164
     * <table border=1 cellpadding=5 summary="lookup method behaviors">
jaroslav@1692
   165
     * <tr>
jaroslav@1692
   166
     *     <th><a name="equiv"></a>lookup expression</th>
jaroslav@1692
   167
     *     <th>member</th>
jaroslav@1692
   168
     *     <th>bytecode behavior</th>
jaroslav@1692
   169
     * </tr>
jaroslav@1692
   170
     * <tr>
jaroslav@1692
   171
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
jaroslav@1692
   172
     *     <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
jaroslav@1692
   173
     * </tr>
jaroslav@1692
   174
     * <tr>
jaroslav@1692
   175
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
jaroslav@1692
   176
     *     <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
jaroslav@1692
   177
     * </tr>
jaroslav@1692
   178
     * <tr>
jaroslav@1692
   179
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
jaroslav@1692
   180
     *     <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
jaroslav@1692
   181
     * </tr>
jaroslav@1692
   182
     * <tr>
jaroslav@1692
   183
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
jaroslav@1692
   184
     *     <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
jaroslav@1692
   185
     * </tr>
jaroslav@1692
   186
     * <tr>
jaroslav@1692
   187
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
jaroslav@1692
   188
     *     <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
jaroslav@1692
   189
     * </tr>
jaroslav@1692
   190
     * <tr>
jaroslav@1692
   191
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
jaroslav@1692
   192
     *     <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
jaroslav@1692
   193
     * </tr>
jaroslav@1692
   194
     * <tr>
jaroslav@1692
   195
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
jaroslav@1692
   196
     *     <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
jaroslav@1692
   197
     * </tr>
jaroslav@1692
   198
     * <tr>
jaroslav@1692
   199
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
jaroslav@1692
   200
     *     <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
jaroslav@1692
   201
     * </tr>
jaroslav@1692
   202
     * <tr>
jaroslav@1692
   203
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
jaroslav@1692
   204
     *     <td>({@code static})?<br>{@code FT f;}</td><td>{@code (FT) aField.get(thisOrNull);}</td>
jaroslav@1692
   205
     * </tr>
jaroslav@1692
   206
     * <tr>
jaroslav@1692
   207
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
jaroslav@1692
   208
     *     <td>({@code static})?<br>{@code FT f;}</td><td>{@code aField.set(thisOrNull, arg);}</td>
jaroslav@1692
   209
     * </tr>
jaroslav@1692
   210
     * <tr>
jaroslav@1692
   211
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
jaroslav@1692
   212
     *     <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
jaroslav@1692
   213
     * </tr>
jaroslav@1692
   214
     * <tr>
jaroslav@1692
   215
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
jaroslav@1692
   216
     *     <td>{@code C(A*);}</td><td>{@code (C) aConstructor.newInstance(arg*);}</td>
jaroslav@1692
   217
     * </tr>
jaroslav@1692
   218
     * <tr>
jaroslav@1692
   219
     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
jaroslav@1692
   220
     *     <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
jaroslav@1692
   221
     * </tr>
jaroslav@1692
   222
     * </table>
jaroslav@1692
   223
     *
jaroslav@1692
   224
     * Here, the type {@code C} is the class or interface being searched for a member,
jaroslav@1692
   225
     * documented as a parameter named {@code refc} in the lookup methods.
jaroslav@1692
   226
     * The method type {@code MT} is composed from the return type {@code T}
jaroslav@1692
   227
     * and the sequence of argument types {@code A*}.
jaroslav@1692
   228
     * The constructor also has a sequence of argument types {@code A*} and
jaroslav@1692
   229
     * is deemed to return the newly-created object of type {@code C}.
jaroslav@1692
   230
     * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
jaroslav@1692
   231
     * The formal parameter {@code this} stands for the self-reference of type {@code C};
jaroslav@1692
   232
     * if it is present, it is always the leading argument to the method handle invocation.
jaroslav@1692
   233
     * (In the case of some {@code protected} members, {@code this} may be
jaroslav@1692
   234
     * restricted in type to the lookup class; see below.)
jaroslav@1692
   235
     * The name {@code arg} stands for all the other method handle arguments.
jaroslav@1692
   236
     * In the code examples for the Core Reflection API, the name {@code thisOrNull}
jaroslav@1692
   237
     * stands for a null reference if the accessed method or field is static,
jaroslav@1692
   238
     * and {@code this} otherwise.
jaroslav@1692
   239
     * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
jaroslav@1692
   240
     * for reflective objects corresponding to the given members.
jaroslav@1692
   241
     * <p>
jaroslav@1692
   242
     * In cases where the given member is of variable arity (i.e., a method or constructor)
jaroslav@1692
   243
     * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
jaroslav@1692
   244
     * In all other cases, the returned method handle will be of fixed arity.
jaroslav@1692
   245
     * <p style="font-size:smaller;">
jaroslav@1692
   246
     * <em>Discussion:</em>
jaroslav@1692
   247
     * The equivalence between looked-up method handles and underlying
jaroslav@1692
   248
     * class members and bytecode behaviors
jaroslav@1692
   249
     * can break down in a few ways:
jaroslav@1692
   250
     * <ul style="font-size:smaller;">
jaroslav@1692
   251
     * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
jaroslav@1692
   252
     * the lookup can still succeed, even when there is no equivalent
jaroslav@1692
   253
     * Java expression or bytecoded constant.
jaroslav@1692
   254
     * <li>Likewise, if {@code T} or {@code MT}
jaroslav@1692
   255
     * is not symbolically accessible from the lookup class's loader,
jaroslav@1692
   256
     * the lookup can still succeed.
jaroslav@1692
   257
     * For example, lookups for {@code MethodHandle.invokeExact} and
jaroslav@1692
   258
     * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
jaroslav@1692
   259
     * <li>If there is a security manager installed, it can forbid the lookup
jaroslav@1692
   260
     * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
jaroslav@1692
   261
     * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
jaroslav@1692
   262
     * constant is not subject to security manager checks.
jaroslav@1692
   263
     * <li>If the looked-up method has a
jaroslav@1692
   264
     * <a href="MethodHandle.html#maxarity">very large arity</a>,
jaroslav@1692
   265
     * the method handle creation may fail, due to the method handle
jaroslav@1692
   266
     * type having too many parameters.
jaroslav@1692
   267
     * </ul>
jaroslav@1692
   268
     *
jaroslav@1692
   269
     * <h1><a name="access"></a>Access checking</h1>
jaroslav@1692
   270
     * Access checks are applied in the factory methods of {@code Lookup},
jaroslav@1692
   271
     * when a method handle is created.
jaroslav@1692
   272
     * This is a key difference from the Core Reflection API, since
jaroslav@1692
   273
     * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
jaroslav@1692
   274
     * performs access checking against every caller, on every call.
jaroslav@1692
   275
     * <p>
jaroslav@1692
   276
     * All access checks start from a {@code Lookup} object, which
jaroslav@1692
   277
     * compares its recorded lookup class against all requests to
jaroslav@1692
   278
     * create method handles.
jaroslav@1692
   279
     * A single {@code Lookup} object can be used to create any number
jaroslav@1692
   280
     * of access-checked method handles, all checked against a single
jaroslav@1692
   281
     * lookup class.
jaroslav@1692
   282
     * <p>
jaroslav@1692
   283
     * A {@code Lookup} object can be shared with other trusted code,
jaroslav@1692
   284
     * such as a metaobject protocol.
jaroslav@1692
   285
     * A shared {@code Lookup} object delegates the capability
jaroslav@1692
   286
     * to create method handles on private members of the lookup class.
jaroslav@1692
   287
     * Even if privileged code uses the {@code Lookup} object,
jaroslav@1692
   288
     * the access checking is confined to the privileges of the
jaroslav@1692
   289
     * original lookup class.
jaroslav@1692
   290
     * <p>
jaroslav@1692
   291
     * A lookup can fail, because
jaroslav@1692
   292
     * the containing class is not accessible to the lookup class, or
jaroslav@1692
   293
     * because the desired class member is missing, or because the
jaroslav@1692
   294
     * desired class member is not accessible to the lookup class, or
jaroslav@1692
   295
     * because the lookup object is not trusted enough to access the member.
jaroslav@1692
   296
     * In any of these cases, a {@code ReflectiveOperationException} will be
jaroslav@1692
   297
     * thrown from the attempted lookup.  The exact class will be one of
jaroslav@1692
   298
     * the following:
jaroslav@1692
   299
     * <ul>
jaroslav@1692
   300
     * <li>NoSuchMethodException &mdash; if a method is requested but does not exist
jaroslav@1692
   301
     * <li>NoSuchFieldException &mdash; if a field is requested but does not exist
jaroslav@1692
   302
     * <li>IllegalAccessException &mdash; if the member exists but an access check fails
jaroslav@1692
   303
     * </ul>
jaroslav@1692
   304
     * <p>
jaroslav@1692
   305
     * In general, the conditions under which a method handle may be
jaroslav@1692
   306
     * looked up for a method {@code M} are no more restrictive than the conditions
jaroslav@1692
   307
     * under which the lookup class could have compiled, verified, and resolved a call to {@code M}.
jaroslav@1692
   308
     * Where the JVM would raise exceptions like {@code NoSuchMethodError},
jaroslav@1692
   309
     * a method handle lookup will generally raise a corresponding
jaroslav@1692
   310
     * checked exception, such as {@code NoSuchMethodException}.
jaroslav@1692
   311
     * And the effect of invoking the method handle resulting from the lookup
jaroslav@1692
   312
     * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a>
jaroslav@1692
   313
     * to executing the compiled, verified, and resolved call to {@code M}.
jaroslav@1692
   314
     * The same point is true of fields and constructors.
jaroslav@1692
   315
     * <p style="font-size:smaller;">
jaroslav@1692
   316
     * <em>Discussion:</em>
jaroslav@1692
   317
     * Access checks only apply to named and reflected methods,
jaroslav@1692
   318
     * constructors, and fields.
jaroslav@1692
   319
     * Other method handle creation methods, such as
jaroslav@1692
   320
     * {@link MethodHandle#asType MethodHandle.asType},
jaroslav@1692
   321
     * do not require any access checks, and are used
jaroslav@1692
   322
     * independently of any {@code Lookup} object.
jaroslav@1692
   323
     * <p>
jaroslav@1692
   324
     * If the desired member is {@code protected}, the usual JVM rules apply,
jaroslav@1692
   325
     * including the requirement that the lookup class must be either be in the
jaroslav@1692
   326
     * same package as the desired member, or must inherit that member.
jaroslav@1692
   327
     * (See the Java Virtual Machine Specification, sections 4.9.2, 5.4.3.5, and 6.4.)
jaroslav@1692
   328
     * In addition, if the desired member is a non-static field or method
jaroslav@1692
   329
     * in a different package, the resulting method handle may only be applied
jaroslav@1692
   330
     * to objects of the lookup class or one of its subclasses.
jaroslav@1692
   331
     * This requirement is enforced by narrowing the type of the leading
jaroslav@1692
   332
     * {@code this} parameter from {@code C}
jaroslav@1692
   333
     * (which will necessarily be a superclass of the lookup class)
jaroslav@1692
   334
     * to the lookup class itself.
jaroslav@1692
   335
     * <p>
jaroslav@1692
   336
     * The JVM imposes a similar requirement on {@code invokespecial} instruction,
jaroslav@1692
   337
     * that the receiver argument must match both the resolved method <em>and</em>
jaroslav@1692
   338
     * the current class.  Again, this requirement is enforced by narrowing the
jaroslav@1692
   339
     * type of the leading parameter to the resulting method handle.
jaroslav@1692
   340
     * (See the Java Virtual Machine Specification, section 4.10.1.9.)
jaroslav@1692
   341
     * <p>
jaroslav@1692
   342
     * The JVM represents constructors and static initializer blocks as internal methods
jaroslav@1692
   343
     * with special names ({@code "<init>"} and {@code "<clinit>"}).
jaroslav@1692
   344
     * The internal syntax of invocation instructions allows them to refer to such internal
jaroslav@1692
   345
     * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
jaroslav@1692
   346
     * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
jaroslav@1692
   347
     * <p>
jaroslav@1692
   348
     * In some cases, access between nested classes is obtained by the Java compiler by creating
jaroslav@1692
   349
     * an wrapper method to access a private method of another class
jaroslav@1692
   350
     * in the same top-level declaration.
jaroslav@1692
   351
     * For example, a nested class {@code C.D}
jaroslav@1692
   352
     * can access private members within other related classes such as
jaroslav@1692
   353
     * {@code C}, {@code C.D.E}, or {@code C.B},
jaroslav@1692
   354
     * but the Java compiler may need to generate wrapper methods in
jaroslav@1692
   355
     * those related classes.  In such cases, a {@code Lookup} object on
jaroslav@1692
   356
     * {@code C.E} would be unable to those private members.
jaroslav@1692
   357
     * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
jaroslav@1692
   358
     * which can transform a lookup on {@code C.E} into one on any of those other
jaroslav@1692
   359
     * classes, without special elevation of privilege.
jaroslav@1692
   360
     * <p>
jaroslav@1692
   361
     * The accesses permitted to a given lookup object may be limited,
jaroslav@1692
   362
     * according to its set of {@link #lookupModes lookupModes},
jaroslav@1692
   363
     * to a subset of members normally accessible to the lookup class.
jaroslav@1692
   364
     * For example, the {@link MethodHandles#publicLookup publicLookup}
jaroslav@1692
   365
     * method produces a lookup object which is only allowed to access
jaroslav@1692
   366
     * public members in public classes.
jaroslav@1692
   367
     * The caller sensitive method {@link MethodHandles#lookup lookup}
jaroslav@1692
   368
     * produces a lookup object with full capabilities relative to
jaroslav@1692
   369
     * its caller class, to emulate all supported bytecode behaviors.
jaroslav@1692
   370
     * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object
jaroslav@1692
   371
     * with fewer access modes than the original lookup object.
jaroslav@1692
   372
     *
jaroslav@1692
   373
     * <p style="font-size:smaller;">
jaroslav@1692
   374
     * <a name="privacc"></a>
jaroslav@1692
   375
     * <em>Discussion of private access:</em>
jaroslav@1692
   376
     * We say that a lookup has <em>private access</em>
jaroslav@1692
   377
     * if its {@linkplain #lookupModes lookup modes}
jaroslav@1692
   378
     * include the possibility of accessing {@code private} members.
jaroslav@1692
   379
     * As documented in the relevant methods elsewhere,
jaroslav@1692
   380
     * only lookups with private access possess the following capabilities:
jaroslav@1692
   381
     * <ul style="font-size:smaller;">
jaroslav@1692
   382
     * <li>access private fields, methods, and constructors of the lookup class
jaroslav@1692
   383
     * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
jaroslav@1692
   384
     *     such as {@code Class.forName}
jaroslav@1692
   385
     * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
jaroslav@1692
   386
     * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
jaroslav@1692
   387
     *     for classes accessible to the lookup class
jaroslav@1692
   388
     * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
jaroslav@1692
   389
     *     within the same package member
jaroslav@1692
   390
     * </ul>
jaroslav@1692
   391
     * <p style="font-size:smaller;">
jaroslav@1692
   392
     * Each of these permissions is a consequence of the fact that a lookup object
jaroslav@1692
   393
     * with private access can be securely traced back to an originating class,
jaroslav@1692
   394
     * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
jaroslav@1692
   395
     * can be reliably determined and emulated by method handles.
jaroslav@1692
   396
     *
jaroslav@1692
   397
     * <h1><a name="secmgr"></a>Security manager interactions</h1>
jaroslav@1692
   398
     * Although bytecode instructions can only refer to classes in
jaroslav@1692
   399
     * a related class loader, this API can search for methods in any
jaroslav@1692
   400
     * class, as long as a reference to its {@code Class} object is
jaroslav@1692
   401
     * available.  Such cross-loader references are also possible with the
jaroslav@1692
   402
     * Core Reflection API, and are impossible to bytecode instructions
jaroslav@1692
   403
     * such as {@code invokestatic} or {@code getfield}.
jaroslav@1692
   404
     * There is a {@linkplain java.lang.SecurityManager security manager API}
jaroslav@1692
   405
     * to allow applications to check such cross-loader references.
jaroslav@1692
   406
     * These checks apply to both the {@code MethodHandles.Lookup} API
jaroslav@1692
   407
     * and the Core Reflection API
jaroslav@1692
   408
     * (as found on {@link java.lang.Class Class}).
jaroslav@1692
   409
     * <p>
jaroslav@1692
   410
     * If a security manager is present, member lookups are subject to
jaroslav@1692
   411
     * additional checks.
jaroslav@1692
   412
     * From one to three calls are made to the security manager.
jaroslav@1692
   413
     * Any of these calls can refuse access by throwing a
jaroslav@1692
   414
     * {@link java.lang.SecurityException SecurityException}.
jaroslav@1692
   415
     * Define {@code smgr} as the security manager,
jaroslav@1692
   416
     * {@code lookc} as the lookup class of the current lookup object,
jaroslav@1692
   417
     * {@code refc} as the containing class in which the member
jaroslav@1692
   418
     * is being sought, and {@code defc} as the class in which the
jaroslav@1692
   419
     * member is actually defined.
jaroslav@1692
   420
     * The value {@code lookc} is defined as <em>not present</em>
jaroslav@1692
   421
     * if the current lookup object does not have
jaroslav@1692
   422
     * <a href="MethodHandles.Lookup.html#privacc">private access</a>.
jaroslav@1692
   423
     * The calls are made according to the following rules:
jaroslav@1692
   424
     * <ul>
jaroslav@1692
   425
     * <li><b>Step 1:</b>
jaroslav@1692
   426
     *     If {@code lookc} is not present, or if its class loader is not
jaroslav@1692
   427
     *     the same as or an ancestor of the class loader of {@code refc},
jaroslav@1692
   428
     *     then {@link SecurityManager#checkPackageAccess
jaroslav@1692
   429
     *     smgr.checkPackageAccess(refcPkg)} is called,
jaroslav@1692
   430
     *     where {@code refcPkg} is the package of {@code refc}.
jaroslav@1692
   431
     * <li><b>Step 2:</b>
jaroslav@1692
   432
     *     If the retrieved member is not public and
jaroslav@1692
   433
     *     {@code lookc} is not present, then
jaroslav@1692
   434
     *     {@link SecurityManager#checkPermission smgr.checkPermission}
jaroslav@1692
   435
     *     with {@code RuntimePermission("accessDeclaredMembers")} is called.
jaroslav@1692
   436
     * <li><b>Step 3:</b>
jaroslav@1692
   437
     *     If the retrieved member is not public,
jaroslav@1692
   438
     *     and if {@code lookc} is not present,
jaroslav@1692
   439
     *     and if {@code defc} and {@code refc} are different,
jaroslav@1692
   440
     *     then {@link SecurityManager#checkPackageAccess
jaroslav@1692
   441
     *     smgr.checkPackageAccess(defcPkg)} is called,
jaroslav@1692
   442
     *     where {@code defcPkg} is the package of {@code defc}.
jaroslav@1692
   443
     * </ul>
jaroslav@1692
   444
     * Security checks are performed after other access checks have passed.
jaroslav@1692
   445
     * Therefore, the above rules presuppose a member that is public,
jaroslav@1692
   446
     * or else that is being accessed from a lookup class that has
jaroslav@1692
   447
     * rights to access the member.
jaroslav@1692
   448
     *
jaroslav@1692
   449
     * <h1><a name="callsens"></a>Caller sensitive methods</h1>
jaroslav@1692
   450
     * A small number of Java methods have a special property called caller sensitivity.
jaroslav@1692
   451
     * A <em>caller-sensitive</em> method can behave differently depending on the
jaroslav@1692
   452
     * identity of its immediate caller.
jaroslav@1692
   453
     * <p>
jaroslav@1692
   454
     * If a method handle for a caller-sensitive method is requested,
jaroslav@1692
   455
     * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
jaroslav@1692
   456
     * but they take account of the lookup class in a special way.
jaroslav@1692
   457
     * The resulting method handle behaves as if it were called
jaroslav@1692
   458
     * from an instruction contained in the lookup class,
jaroslav@1692
   459
     * so that the caller-sensitive method detects the lookup class.
jaroslav@1692
   460
     * (By contrast, the invoker of the method handle is disregarded.)
jaroslav@1692
   461
     * Thus, in the case of caller-sensitive methods,
jaroslav@1692
   462
     * different lookup classes may give rise to
jaroslav@1692
   463
     * differently behaving method handles.
jaroslav@1692
   464
     * <p>
jaroslav@1692
   465
     * In cases where the lookup object is
jaroslav@1692
   466
     * {@link MethodHandles#publicLookup() publicLookup()},
jaroslav@1692
   467
     * or some other lookup object without
jaroslav@1692
   468
     * <a href="MethodHandles.Lookup.html#privacc">private access</a>,
jaroslav@1692
   469
     * the lookup class is disregarded.
jaroslav@1692
   470
     * In such cases, no caller-sensitive method handle can be created,
jaroslav@1692
   471
     * access is forbidden, and the lookup fails with an
jaroslav@1692
   472
     * {@code IllegalAccessException}.
jaroslav@1692
   473
     * <p style="font-size:smaller;">
jaroslav@1692
   474
     * <em>Discussion:</em>
jaroslav@1692
   475
     * For example, the caller-sensitive method
jaroslav@1692
   476
     * {@link java.lang.Class#forName(String) Class.forName(x)}
jaroslav@1692
   477
     * can return varying classes or throw varying exceptions,
jaroslav@1692
   478
     * depending on the class loader of the class that calls it.
jaroslav@1692
   479
     * A public lookup of {@code Class.forName} will fail, because
jaroslav@1692
   480
     * there is no reasonable way to determine its bytecode behavior.
jaroslav@1692
   481
     * <p style="font-size:smaller;">
jaroslav@1692
   482
     * If an application caches method handles for broad sharing,
jaroslav@1692
   483
     * it should use {@code publicLookup()} to create them.
jaroslav@1692
   484
     * If there is a lookup of {@code Class.forName}, it will fail,
jaroslav@1692
   485
     * and the application must take appropriate action in that case.
jaroslav@1692
   486
     * It may be that a later lookup, perhaps during the invocation of a
jaroslav@1692
   487
     * bootstrap method, can incorporate the specific identity
jaroslav@1692
   488
     * of the caller, making the method accessible.
jaroslav@1692
   489
     * <p style="font-size:smaller;">
jaroslav@1692
   490
     * The function {@code MethodHandles.lookup} is caller sensitive
jaroslav@1692
   491
     * so that there can be a secure foundation for lookups.
jaroslav@1692
   492
     * Nearly all other methods in the JSR 292 API rely on lookup
jaroslav@1692
   493
     * objects to check access requests.
jaroslav@1692
   494
     */
jaroslav@1692
   495
    public static final
jaroslav@1692
   496
    class Lookup {
jaroslav@1692
   497
        /** The class on behalf of whom the lookup is being performed. */
jaroslav@1692
   498
        private final Class<?> lookupClass;
jaroslav@1692
   499
jaroslav@1692
   500
        /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
jaroslav@1692
   501
        private final int allowedModes;
jaroslav@1692
   502
jaroslav@1692
   503
        /** A single-bit mask representing {@code public} access,
jaroslav@1692
   504
         *  which may contribute to the result of {@link #lookupModes lookupModes}.
jaroslav@1692
   505
         *  The value, {@code 0x01}, happens to be the same as the value of the
jaroslav@1692
   506
         *  {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
jaroslav@1692
   507
         */
jaroslav@1692
   508
        public static final int PUBLIC = Modifier.PUBLIC;
jaroslav@1692
   509
jaroslav@1692
   510
        /** A single-bit mask representing {@code private} access,
jaroslav@1692
   511
         *  which may contribute to the result of {@link #lookupModes lookupModes}.
jaroslav@1692
   512
         *  The value, {@code 0x02}, happens to be the same as the value of the
jaroslav@1692
   513
         *  {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
jaroslav@1692
   514
         */
jaroslav@1692
   515
        public static final int PRIVATE = Modifier.PRIVATE;
jaroslav@1692
   516
jaroslav@1692
   517
        /** A single-bit mask representing {@code protected} access,
jaroslav@1692
   518
         *  which may contribute to the result of {@link #lookupModes lookupModes}.
jaroslav@1692
   519
         *  The value, {@code 0x04}, happens to be the same as the value of the
jaroslav@1692
   520
         *  {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
jaroslav@1692
   521
         */
jaroslav@1692
   522
        public static final int PROTECTED = Modifier.PROTECTED;
jaroslav@1692
   523
jaroslav@1692
   524
        /** A single-bit mask representing {@code package} access (default access),
jaroslav@1692
   525
         *  which may contribute to the result of {@link #lookupModes lookupModes}.
jaroslav@1692
   526
         *  The value is {@code 0x08}, which does not correspond meaningfully to
jaroslav@1692
   527
         *  any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
jaroslav@1692
   528
         */
jaroslav@1692
   529
        public static final int PACKAGE = Modifier.STATIC;
jaroslav@1692
   530
jaroslav@1692
   531
        private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
jaroslav@1692
   532
        private static final int TRUSTED   = -1;
jaroslav@1692
   533
jaroslav@1692
   534
        private static int fixmods(int mods) {
jaroslav@1692
   535
            mods &= (ALL_MODES - PACKAGE);
jaroslav@1692
   536
            return (mods != 0) ? mods : PACKAGE;
jaroslav@1692
   537
        }
jaroslav@1692
   538
jaroslav@1692
   539
        /** Tells which class is performing the lookup.  It is this class against
jaroslav@1692
   540
         *  which checks are performed for visibility and access permissions.
jaroslav@1692
   541
         *  <p>
jaroslav@1692
   542
         *  The class implies a maximum level of access permission,
jaroslav@1692
   543
         *  but the permissions may be additionally limited by the bitmask
jaroslav@1692
   544
         *  {@link #lookupModes lookupModes}, which controls whether non-public members
jaroslav@1692
   545
         *  can be accessed.
jaroslav@1692
   546
         *  @return the lookup class, on behalf of which this lookup object finds members
jaroslav@1692
   547
         */
jaroslav@1692
   548
        public Class<?> lookupClass() {
jaroslav@1692
   549
            return lookupClass;
jaroslav@1692
   550
        }
jaroslav@1692
   551
jaroslav@1692
   552
        // This is just for calling out to MethodHandleImpl.
jaroslav@1692
   553
        private Class<?> lookupClassOrNull() {
jaroslav@1692
   554
            return (allowedModes == TRUSTED) ? null : lookupClass;
jaroslav@1692
   555
        }
jaroslav@1692
   556
jaroslav@1692
   557
        /** Tells which access-protection classes of members this lookup object can produce.
jaroslav@1692
   558
         *  The result is a bit-mask of the bits
jaroslav@1692
   559
         *  {@linkplain #PUBLIC PUBLIC (0x01)},
jaroslav@1692
   560
         *  {@linkplain #PRIVATE PRIVATE (0x02)},
jaroslav@1692
   561
         *  {@linkplain #PROTECTED PROTECTED (0x04)},
jaroslav@1692
   562
         *  and {@linkplain #PACKAGE PACKAGE (0x08)}.
jaroslav@1692
   563
         *  <p>
jaroslav@1692
   564
         *  A freshly-created lookup object
jaroslav@1692
   565
         *  on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
jaroslav@1692
   566
         *  has all possible bits set, since the caller class can access all its own members.
jaroslav@1692
   567
         *  A lookup object on a new lookup class
jaroslav@1692
   568
         *  {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
jaroslav@1692
   569
         *  may have some mode bits set to zero.
jaroslav@1692
   570
         *  The purpose of this is to restrict access via the new lookup object,
jaroslav@1692
   571
         *  so that it can access only names which can be reached by the original
jaroslav@1692
   572
         *  lookup object, and also by the new lookup class.
jaroslav@1692
   573
         *  @return the lookup modes, which limit the kinds of access performed by this lookup object
jaroslav@1692
   574
         */
jaroslav@1692
   575
        public int lookupModes() {
jaroslav@1692
   576
            return allowedModes & ALL_MODES;
jaroslav@1692
   577
        }
jaroslav@1692
   578
jaroslav@1692
   579
        /** Embody the current class (the lookupClass) as a lookup class
jaroslav@1692
   580
         * for method handle creation.
jaroslav@1692
   581
         * Must be called by from a method in this package,
jaroslav@1692
   582
         * which in turn is called by a method not in this package.
jaroslav@1692
   583
         */
jaroslav@1692
   584
        Lookup(Class<?> lookupClass) {
jaroslav@1692
   585
            this(lookupClass, ALL_MODES);
jaroslav@1692
   586
            // make sure we haven't accidentally picked up a privileged class:
jaroslav@1692
   587
        }
jaroslav@1692
   588
jaroslav@1692
   589
        private Lookup(Class<?> lookupClass, int allowedModes) {
jaroslav@1692
   590
            this.lookupClass = lookupClass;
jaroslav@1692
   591
            this.allowedModes = allowedModes;
jaroslav@1692
   592
        }
jaroslav@1692
   593
jaroslav@1692
   594
        /**
jaroslav@1692
   595
         * Creates a lookup on the specified new lookup class.
jaroslav@1692
   596
         * The resulting object will report the specified
jaroslav@1692
   597
         * class as its own {@link #lookupClass lookupClass}.
jaroslav@1692
   598
         * <p>
jaroslav@1692
   599
         * However, the resulting {@code Lookup} object is guaranteed
jaroslav@1692
   600
         * to have no more access capabilities than the original.
jaroslav@1692
   601
         * In particular, access capabilities can be lost as follows:<ul>
jaroslav@1692
   602
         * <li>If the new lookup class differs from the old one,
jaroslav@1692
   603
         * protected members will not be accessible by virtue of inheritance.
jaroslav@1692
   604
         * (Protected members may continue to be accessible because of package sharing.)
jaroslav@1692
   605
         * <li>If the new lookup class is in a different package
jaroslav@1692
   606
         * than the old one, protected and default (package) members will not be accessible.
jaroslav@1692
   607
         * <li>If the new lookup class is not within the same package member
jaroslav@1692
   608
         * as the old one, private members will not be accessible.
jaroslav@1692
   609
         * <li>If the new lookup class is not accessible to the old lookup class,
jaroslav@1692
   610
         * then no members, not even public members, will be accessible.
jaroslav@1692
   611
         * (In all other cases, public members will continue to be accessible.)
jaroslav@1692
   612
         * </ul>
jaroslav@1692
   613
         *
jaroslav@1692
   614
         * @param requestedLookupClass the desired lookup class for the new lookup object
jaroslav@1692
   615
         * @return a lookup object which reports the desired lookup class
jaroslav@1692
   616
         * @throws NullPointerException if the argument is null
jaroslav@1692
   617
         */
jaroslav@1692
   618
        public Lookup in(Class<?> requestedLookupClass) {
jaroslav@1692
   619
            throw new IllegalStateException();
jaroslav@1692
   620
        }
jaroslav@1692
   621
jaroslav@1692
   622
        /** Version of lookup which is trusted minimally.
jaroslav@1692
   623
         *  It can only be used to create method handles to
jaroslav@1692
   624
         *  publicly accessible members.
jaroslav@1692
   625
         */
jaroslav@1692
   626
        static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
jaroslav@1692
   627
jaroslav@1692
   628
        /** Package-private version of lookup which is trusted. */
jaroslav@1692
   629
        static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
jaroslav@1692
   630
jaroslav@1692
   631
        /**
jaroslav@1692
   632
         * Displays the name of the class from which lookups are to be made.
jaroslav@1692
   633
         * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
jaroslav@1692
   634
         * If there are restrictions on the access permitted to this lookup,
jaroslav@1692
   635
         * this is indicated by adding a suffix to the class name, consisting
jaroslav@1692
   636
         * of a slash and a keyword.  The keyword represents the strongest
jaroslav@1692
   637
         * allowed access, and is chosen as follows:
jaroslav@1692
   638
         * <ul>
jaroslav@1692
   639
         * <li>If no access is allowed, the suffix is "/noaccess".
jaroslav@1692
   640
         * <li>If only public access is allowed, the suffix is "/public".
jaroslav@1692
   641
         * <li>If only public and package access are allowed, the suffix is "/package".
jaroslav@1692
   642
         * <li>If only public, package, and private access are allowed, the suffix is "/private".
jaroslav@1692
   643
         * </ul>
jaroslav@1692
   644
         * If none of the above cases apply, it is the case that full
jaroslav@1692
   645
         * access (public, package, private, and protected) is allowed.
jaroslav@1692
   646
         * In this case, no suffix is added.
jaroslav@1692
   647
         * This is true only of an object obtained originally from
jaroslav@1692
   648
         * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
jaroslav@1692
   649
         * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
jaroslav@1692
   650
         * always have restricted access, and will display a suffix.
jaroslav@1692
   651
         * <p>
jaroslav@1692
   652
         * (It may seem strange that protected access should be
jaroslav@1692
   653
         * stronger than private access.  Viewed independently from
jaroslav@1692
   654
         * package access, protected access is the first to be lost,
jaroslav@1692
   655
         * because it requires a direct subclass relationship between
jaroslav@1692
   656
         * caller and callee.)
jaroslav@1692
   657
         * @see #in
jaroslav@1692
   658
         */
jaroslav@1692
   659
        @Override
jaroslav@1692
   660
        public String toString() {
jaroslav@1692
   661
            String cname = lookupClass.getName();
jaroslav@1692
   662
            switch (allowedModes) {
jaroslav@1692
   663
            case 0:  // no privileges
jaroslav@1692
   664
                return cname + "/noaccess";
jaroslav@1692
   665
            case PUBLIC:
jaroslav@1692
   666
                return cname + "/public";
jaroslav@1692
   667
            case PUBLIC|PACKAGE:
jaroslav@1692
   668
                return cname + "/package";
jaroslav@1692
   669
            case ALL_MODES & ~PROTECTED:
jaroslav@1692
   670
                return cname + "/private";
jaroslav@1692
   671
            case ALL_MODES:
jaroslav@1692
   672
                return cname;
jaroslav@1692
   673
            case TRUSTED:
jaroslav@1692
   674
                return "/trusted";  // internal only; not exported
jaroslav@1692
   675
            default:  // Should not happen, but it's a bitfield...
jaroslav@1692
   676
                cname = cname + "/" + Integer.toHexString(allowedModes);
jaroslav@1692
   677
                assert(false) : cname;
jaroslav@1692
   678
                return cname;
jaroslav@1692
   679
            }
jaroslav@1692
   680
        }
jaroslav@1692
   681
jaroslav@1692
   682
        /**
jaroslav@1692
   683
         * Produces a method handle for a static method.
jaroslav@1692
   684
         * The type of the method handle will be that of the method.
jaroslav@1692
   685
         * (Since static methods do not take receivers, there is no
jaroslav@1692
   686
         * additional receiver argument inserted into the method handle type,
jaroslav@1692
   687
         * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
jaroslav@1692
   688
         * The method and all its argument types must be accessible to the lookup object.
jaroslav@1692
   689
         * <p>
jaroslav@1692
   690
         * The returned method handle will have
jaroslav@1692
   691
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
jaroslav@1692
   692
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
jaroslav@1692
   693
         * <p>
jaroslav@1692
   694
         * If the returned method handle is invoked, the method's class will
jaroslav@1692
   695
         * be initialized, if it has not already been initialized.
jaroslav@1692
   696
         * <p><b>Example:</b>
jaroslav@1692
   697
         * <blockquote><pre>{@code
jaroslav@1692
   698
import static java.lang.invoke.MethodHandles.*;
jaroslav@1692
   699
import static java.lang.invoke.MethodType.*;
jaroslav@1692
   700
...
jaroslav@1692
   701
MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
jaroslav@1692
   702
  "asList", methodType(List.class, Object[].class));
jaroslav@1692
   703
assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
jaroslav@1692
   704
         * }</pre></blockquote>
jaroslav@1692
   705
         * @param refc the class from which the method is accessed
jaroslav@1692
   706
         * @param name the name of the method
jaroslav@1692
   707
         * @param type the type of the method
jaroslav@1692
   708
         * @return the desired method handle
jaroslav@1692
   709
         * @throws NoSuchMethodException if the method does not exist
jaroslav@1692
   710
         * @throws IllegalAccessException if access checking fails,
jaroslav@1692
   711
         *                                or if the method is not {@code static},
jaroslav@1692
   712
         *                                or if the method's variable arity modifier bit
jaroslav@1692
   713
         *                                is set and {@code asVarargsCollector} fails
jaroslav@1692
   714
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
   715
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
   716
         * @throws NullPointerException if any argument is null
jaroslav@1692
   717
         */
jaroslav@1692
   718
        public
jaroslav@1692
   719
        MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
jaroslav@1692
   720
            throw new IllegalStateException();
jaroslav@1692
   721
        }
jaroslav@1692
   722
jaroslav@1692
   723
        /**
jaroslav@1692
   724
         * Produces a method handle for a virtual method.
jaroslav@1692
   725
         * The type of the method handle will be that of the method,
jaroslav@1692
   726
         * with the receiver type (usually {@code refc}) prepended.
jaroslav@1692
   727
         * The method and all its argument types must be accessible to the lookup object.
jaroslav@1692
   728
         * <p>
jaroslav@1692
   729
         * When called, the handle will treat the first argument as a receiver
jaroslav@1692
   730
         * and dispatch on the receiver's type to determine which method
jaroslav@1692
   731
         * implementation to enter.
jaroslav@1692
   732
         * (The dispatching action is identical with that performed by an
jaroslav@1692
   733
         * {@code invokevirtual} or {@code invokeinterface} instruction.)
jaroslav@1692
   734
         * <p>
jaroslav@1692
   735
         * The first argument will be of type {@code refc} if the lookup
jaroslav@1692
   736
         * class has full privileges to access the member.  Otherwise
jaroslav@1692
   737
         * the member must be {@code protected} and the first argument
jaroslav@1692
   738
         * will be restricted in type to the lookup class.
jaroslav@1692
   739
         * <p>
jaroslav@1692
   740
         * The returned method handle will have
jaroslav@1692
   741
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
jaroslav@1692
   742
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
jaroslav@1692
   743
         * <p>
jaroslav@1692
   744
         * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual}
jaroslav@1692
   745
         * instructions and method handles produced by {@code findVirtual},
jaroslav@1692
   746
         * if the class is {@code MethodHandle} and the name string is
jaroslav@1692
   747
         * {@code invokeExact} or {@code invoke}, the resulting
jaroslav@1692
   748
         * method handle is equivalent to one produced by
jaroslav@1692
   749
         * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
jaroslav@1692
   750
         * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
jaroslav@1692
   751
         * with the same {@code type} argument.
jaroslav@1692
   752
         *
jaroslav@1692
   753
         * <b>Example:</b>
jaroslav@1692
   754
         * <blockquote><pre>{@code
jaroslav@1692
   755
import static java.lang.invoke.MethodHandles.*;
jaroslav@1692
   756
import static java.lang.invoke.MethodType.*;
jaroslav@1692
   757
...
jaroslav@1692
   758
MethodHandle MH_concat = publicLookup().findVirtual(String.class,
jaroslav@1692
   759
  "concat", methodType(String.class, String.class));
jaroslav@1692
   760
MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
jaroslav@1692
   761
  "hashCode", methodType(int.class));
jaroslav@1692
   762
MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
jaroslav@1692
   763
  "hashCode", methodType(int.class));
jaroslav@1692
   764
assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
jaroslav@1692
   765
assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
jaroslav@1692
   766
assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
jaroslav@1692
   767
// interface method:
jaroslav@1692
   768
MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
jaroslav@1692
   769
  "subSequence", methodType(CharSequence.class, int.class, int.class));
jaroslav@1692
   770
assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
jaroslav@1692
   771
// constructor "internal method" must be accessed differently:
jaroslav@1692
   772
MethodType MT_newString = methodType(void.class); //()V for new String()
jaroslav@1692
   773
try { assertEquals("impossible", lookup()
jaroslav@1692
   774
        .findVirtual(String.class, "<init>", MT_newString));
jaroslav@1692
   775
 } catch (NoSuchMethodException ex) { } // OK
jaroslav@1692
   776
MethodHandle MH_newString = publicLookup()
jaroslav@1692
   777
  .findConstructor(String.class, MT_newString);
jaroslav@1692
   778
assertEquals("", (String) MH_newString.invokeExact());
jaroslav@1692
   779
         * }</pre></blockquote>
jaroslav@1692
   780
         *
jaroslav@1692
   781
         * @param refc the class or interface from which the method is accessed
jaroslav@1692
   782
         * @param name the name of the method
jaroslav@1692
   783
         * @param type the type of the method, with the receiver argument omitted
jaroslav@1692
   784
         * @return the desired method handle
jaroslav@1692
   785
         * @throws NoSuchMethodException if the method does not exist
jaroslav@1692
   786
         * @throws IllegalAccessException if access checking fails,
jaroslav@1692
   787
         *                                or if the method is {@code static}
jaroslav@1692
   788
         *                                or if the method's variable arity modifier bit
jaroslav@1692
   789
         *                                is set and {@code asVarargsCollector} fails
jaroslav@1692
   790
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
   791
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
   792
         * @throws NullPointerException if any argument is null
jaroslav@1692
   793
         */
jaroslav@1692
   794
        public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
jaroslav@1692
   795
            throw new IllegalStateException();
jaroslav@1692
   796
        }
jaroslav@1692
   797
jaroslav@1692
   798
        /**
jaroslav@1692
   799
         * Produces a method handle which creates an object and initializes it, using
jaroslav@1692
   800
         * the constructor of the specified type.
jaroslav@1692
   801
         * The parameter types of the method handle will be those of the constructor,
jaroslav@1692
   802
         * while the return type will be a reference to the constructor's class.
jaroslav@1692
   803
         * The constructor and all its argument types must be accessible to the lookup object.
jaroslav@1692
   804
         * <p>
jaroslav@1692
   805
         * The requested type must have a return type of {@code void}.
jaroslav@1692
   806
         * (This is consistent with the JVM's treatment of constructor type descriptors.)
jaroslav@1692
   807
         * <p>
jaroslav@1692
   808
         * The returned method handle will have
jaroslav@1692
   809
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
jaroslav@1692
   810
         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
jaroslav@1692
   811
         * <p>
jaroslav@1692
   812
         * If the returned method handle is invoked, the constructor's class will
jaroslav@1692
   813
         * be initialized, if it has not already been initialized.
jaroslav@1692
   814
         * <p><b>Example:</b>
jaroslav@1692
   815
         * <blockquote><pre>{@code
jaroslav@1692
   816
import static java.lang.invoke.MethodHandles.*;
jaroslav@1692
   817
import static java.lang.invoke.MethodType.*;
jaroslav@1692
   818
...
jaroslav@1692
   819
MethodHandle MH_newArrayList = publicLookup().findConstructor(
jaroslav@1692
   820
  ArrayList.class, methodType(void.class, Collection.class));
jaroslav@1692
   821
Collection orig = Arrays.asList("x", "y");
jaroslav@1692
   822
Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
jaroslav@1692
   823
assert(orig != copy);
jaroslav@1692
   824
assertEquals(orig, copy);
jaroslav@1692
   825
// a variable-arity constructor:
jaroslav@1692
   826
MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
jaroslav@1692
   827
  ProcessBuilder.class, methodType(void.class, String[].class));
jaroslav@1692
   828
ProcessBuilder pb = (ProcessBuilder)
jaroslav@1692
   829
  MH_newProcessBuilder.invoke("x", "y", "z");
jaroslav@1692
   830
assertEquals("[x, y, z]", pb.command().toString());
jaroslav@1692
   831
         * }</pre></blockquote>
jaroslav@1692
   832
         * @param refc the class or interface from which the method is accessed
jaroslav@1692
   833
         * @param type the type of the method, with the receiver argument omitted, and a void return type
jaroslav@1692
   834
         * @return the desired method handle
jaroslav@1692
   835
         * @throws NoSuchMethodException if the constructor does not exist
jaroslav@1692
   836
         * @throws IllegalAccessException if access checking fails
jaroslav@1692
   837
         *                                or if the method's variable arity modifier bit
jaroslav@1692
   838
         *                                is set and {@code asVarargsCollector} fails
jaroslav@1692
   839
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
   840
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
   841
         * @throws NullPointerException if any argument is null
jaroslav@1692
   842
         */
jaroslav@1692
   843
        public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
jaroslav@1692
   844
            throw new IllegalStateException();
jaroslav@1692
   845
        }
jaroslav@1692
   846
jaroslav@1692
   847
        /**
jaroslav@1692
   848
         * Produces an early-bound method handle for a virtual method.
jaroslav@1692
   849
         * It will bypass checks for overriding methods on the receiver,
jaroslav@1692
   850
         * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
jaroslav@1692
   851
         * instruction from within the explicitly specified {@code specialCaller}.
jaroslav@1692
   852
         * The type of the method handle will be that of the method,
jaroslav@1692
   853
         * with a suitably restricted receiver type prepended.
jaroslav@1692
   854
         * (The receiver type will be {@code specialCaller} or a subtype.)
jaroslav@1692
   855
         * The method and all its argument types must be accessible
jaroslav@1692
   856
         * to the lookup object.
jaroslav@1692
   857
         * <p>
jaroslav@1692
   858
         * Before method resolution,
jaroslav@1692
   859
         * if the explicitly specified caller class is not identical with the
jaroslav@1692
   860
         * lookup class, or if this lookup object does not have
jaroslav@1692
   861
         * <a href="MethodHandles.Lookup.html#privacc">private access</a>
jaroslav@1692
   862
         * privileges, the access fails.
jaroslav@1692
   863
         * <p>
jaroslav@1692
   864
         * The returned method handle will have
jaroslav@1692
   865
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
jaroslav@1692
   866
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
jaroslav@1692
   867
         * <p style="font-size:smaller;">
jaroslav@1692
   868
         * <em>(Note:  JVM internal methods named {@code "<init>"} are not visible to this API,
jaroslav@1692
   869
         * even though the {@code invokespecial} instruction can refer to them
jaroslav@1692
   870
         * in special circumstances.  Use {@link #findConstructor findConstructor}
jaroslav@1692
   871
         * to access instance initialization methods in a safe manner.)</em>
jaroslav@1692
   872
         * <p><b>Example:</b>
jaroslav@1692
   873
         * <blockquote><pre>{@code
jaroslav@1692
   874
import static java.lang.invoke.MethodHandles.*;
jaroslav@1692
   875
import static java.lang.invoke.MethodType.*;
jaroslav@1692
   876
...
jaroslav@1692
   877
static class Listie extends ArrayList {
jaroslav@1692
   878
  public String toString() { return "[wee Listie]"; }
jaroslav@1692
   879
  static Lookup lookup() { return MethodHandles.lookup(); }
jaroslav@1692
   880
}
jaroslav@1692
   881
...
jaroslav@1692
   882
// no access to constructor via invokeSpecial:
jaroslav@1692
   883
MethodHandle MH_newListie = Listie.lookup()
jaroslav@1692
   884
  .findConstructor(Listie.class, methodType(void.class));
jaroslav@1692
   885
Listie l = (Listie) MH_newListie.invokeExact();
jaroslav@1692
   886
try { assertEquals("impossible", Listie.lookup().findSpecial(
jaroslav@1692
   887
        Listie.class, "<init>", methodType(void.class), Listie.class));
jaroslav@1692
   888
 } catch (NoSuchMethodException ex) { } // OK
jaroslav@1692
   889
// access to super and self methods via invokeSpecial:
jaroslav@1692
   890
MethodHandle MH_super = Listie.lookup().findSpecial(
jaroslav@1692
   891
  ArrayList.class, "toString" , methodType(String.class), Listie.class);
jaroslav@1692
   892
MethodHandle MH_this = Listie.lookup().findSpecial(
jaroslav@1692
   893
  Listie.class, "toString" , methodType(String.class), Listie.class);
jaroslav@1692
   894
MethodHandle MH_duper = Listie.lookup().findSpecial(
jaroslav@1692
   895
  Object.class, "toString" , methodType(String.class), Listie.class);
jaroslav@1692
   896
assertEquals("[]", (String) MH_super.invokeExact(l));
jaroslav@1692
   897
assertEquals(""+l, (String) MH_this.invokeExact(l));
jaroslav@1692
   898
assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
jaroslav@1692
   899
try { assertEquals("inaccessible", Listie.lookup().findSpecial(
jaroslav@1692
   900
        String.class, "toString", methodType(String.class), Listie.class));
jaroslav@1692
   901
 } catch (IllegalAccessException ex) { } // OK
jaroslav@1692
   902
Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
jaroslav@1692
   903
assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
jaroslav@1692
   904
         * }</pre></blockquote>
jaroslav@1692
   905
         *
jaroslav@1692
   906
         * @param refc the class or interface from which the method is accessed
jaroslav@1692
   907
         * @param name the name of the method (which must not be "&lt;init&gt;")
jaroslav@1692
   908
         * @param type the type of the method, with the receiver argument omitted
jaroslav@1692
   909
         * @param specialCaller the proposed calling class to perform the {@code invokespecial}
jaroslav@1692
   910
         * @return the desired method handle
jaroslav@1692
   911
         * @throws NoSuchMethodException if the method does not exist
jaroslav@1692
   912
         * @throws IllegalAccessException if access checking fails
jaroslav@1692
   913
         *                                or if the method's variable arity modifier bit
jaroslav@1692
   914
         *                                is set and {@code asVarargsCollector} fails
jaroslav@1692
   915
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
   916
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
   917
         * @throws NullPointerException if any argument is null
jaroslav@1692
   918
         */
jaroslav@1692
   919
        public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
jaroslav@1692
   920
                                        Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
jaroslav@1692
   921
            throw new IllegalStateException();
jaroslav@1692
   922
        }
jaroslav@1692
   923
jaroslav@1692
   924
        /**
jaroslav@1692
   925
         * Produces a method handle giving read access to a non-static field.
jaroslav@1692
   926
         * The type of the method handle will have a return type of the field's
jaroslav@1692
   927
         * value type.
jaroslav@1692
   928
         * The method handle's single argument will be the instance containing
jaroslav@1692
   929
         * the field.
jaroslav@1692
   930
         * Access checking is performed immediately on behalf of the lookup class.
jaroslav@1692
   931
         * @param refc the class or interface from which the method is accessed
jaroslav@1692
   932
         * @param name the field's name
jaroslav@1692
   933
         * @param type the field's type
jaroslav@1692
   934
         * @return a method handle which can load values from the field
jaroslav@1692
   935
         * @throws NoSuchFieldException if the field does not exist
jaroslav@1692
   936
         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
jaroslav@1692
   937
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
   938
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
   939
         * @throws NullPointerException if any argument is null
jaroslav@1692
   940
         */
jaroslav@1692
   941
        public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
jaroslav@1692
   942
            throw new IllegalStateException();
jaroslav@1692
   943
        }
jaroslav@1692
   944
jaroslav@1692
   945
        /**
jaroslav@1692
   946
         * Produces a method handle giving write access to a non-static field.
jaroslav@1692
   947
         * The type of the method handle will have a void return type.
jaroslav@1692
   948
         * The method handle will take two arguments, the instance containing
jaroslav@1692
   949
         * the field, and the value to be stored.
jaroslav@1692
   950
         * The second argument will be of the field's value type.
jaroslav@1692
   951
         * Access checking is performed immediately on behalf of the lookup class.
jaroslav@1692
   952
         * @param refc the class or interface from which the method is accessed
jaroslav@1692
   953
         * @param name the field's name
jaroslav@1692
   954
         * @param type the field's type
jaroslav@1692
   955
         * @return a method handle which can store values into the field
jaroslav@1692
   956
         * @throws NoSuchFieldException if the field does not exist
jaroslav@1692
   957
         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
jaroslav@1692
   958
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
   959
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
   960
         * @throws NullPointerException if any argument is null
jaroslav@1692
   961
         */
jaroslav@1692
   962
        public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
jaroslav@1692
   963
            throw new IllegalStateException();
jaroslav@1692
   964
        }
jaroslav@1692
   965
jaroslav@1692
   966
        /**
jaroslav@1692
   967
         * Produces a method handle giving read access to a static field.
jaroslav@1692
   968
         * The type of the method handle will have a return type of the field's
jaroslav@1692
   969
         * value type.
jaroslav@1692
   970
         * The method handle will take no arguments.
jaroslav@1692
   971
         * Access checking is performed immediately on behalf of the lookup class.
jaroslav@1692
   972
         * <p>
jaroslav@1692
   973
         * If the returned method handle is invoked, the field's class will
jaroslav@1692
   974
         * be initialized, if it has not already been initialized.
jaroslav@1692
   975
         * @param refc the class or interface from which the method is accessed
jaroslav@1692
   976
         * @param name the field's name
jaroslav@1692
   977
         * @param type the field's type
jaroslav@1692
   978
         * @return a method handle which can load values from the field
jaroslav@1692
   979
         * @throws NoSuchFieldException if the field does not exist
jaroslav@1692
   980
         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
jaroslav@1692
   981
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
   982
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
   983
         * @throws NullPointerException if any argument is null
jaroslav@1692
   984
         */
jaroslav@1692
   985
        public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
jaroslav@1692
   986
            throw new IllegalStateException();
jaroslav@1692
   987
        }
jaroslav@1692
   988
jaroslav@1692
   989
        /**
jaroslav@1692
   990
         * Produces a method handle giving write access to a static field.
jaroslav@1692
   991
         * The type of the method handle will have a void return type.
jaroslav@1692
   992
         * The method handle will take a single
jaroslav@1692
   993
         * argument, of the field's value type, the value to be stored.
jaroslav@1692
   994
         * Access checking is performed immediately on behalf of the lookup class.
jaroslav@1692
   995
         * <p>
jaroslav@1692
   996
         * If the returned method handle is invoked, the field's class will
jaroslav@1692
   997
         * be initialized, if it has not already been initialized.
jaroslav@1692
   998
         * @param refc the class or interface from which the method is accessed
jaroslav@1692
   999
         * @param name the field's name
jaroslav@1692
  1000
         * @param type the field's type
jaroslav@1692
  1001
         * @return a method handle which can store values into the field
jaroslav@1692
  1002
         * @throws NoSuchFieldException if the field does not exist
jaroslav@1692
  1003
         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
jaroslav@1692
  1004
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
  1005
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
  1006
         * @throws NullPointerException if any argument is null
jaroslav@1692
  1007
         */
jaroslav@1692
  1008
        public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
jaroslav@1692
  1009
            throw new IllegalStateException();
jaroslav@1692
  1010
        }
jaroslav@1692
  1011
jaroslav@1692
  1012
        /**
jaroslav@1692
  1013
         * Produces an early-bound method handle for a non-static method.
jaroslav@1692
  1014
         * The receiver must have a supertype {@code defc} in which a method
jaroslav@1692
  1015
         * of the given name and type is accessible to the lookup class.
jaroslav@1692
  1016
         * The method and all its argument types must be accessible to the lookup object.
jaroslav@1692
  1017
         * The type of the method handle will be that of the method,
jaroslav@1692
  1018
         * without any insertion of an additional receiver parameter.
jaroslav@1692
  1019
         * The given receiver will be bound into the method handle,
jaroslav@1692
  1020
         * so that every call to the method handle will invoke the
jaroslav@1692
  1021
         * requested method on the given receiver.
jaroslav@1692
  1022
         * <p>
jaroslav@1692
  1023
         * The returned method handle will have
jaroslav@1692
  1024
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
jaroslav@1692
  1025
         * the method's variable arity modifier bit ({@code 0x0080}) is set
jaroslav@1692
  1026
         * <em>and</em> the trailing array argument is not the only argument.
jaroslav@1692
  1027
         * (If the trailing array argument is the only argument,
jaroslav@1692
  1028
         * the given receiver value will be bound to it.)
jaroslav@1692
  1029
         * <p>
jaroslav@1692
  1030
         * This is equivalent to the following code:
jaroslav@1692
  1031
         * <blockquote><pre>{@code
jaroslav@1692
  1032
import static java.lang.invoke.MethodHandles.*;
jaroslav@1692
  1033
import static java.lang.invoke.MethodType.*;
jaroslav@1692
  1034
...
jaroslav@1692
  1035
MethodHandle mh0 = lookup().findVirtual(defc, name, type);
jaroslav@1692
  1036
MethodHandle mh1 = mh0.bindTo(receiver);
jaroslav@1692
  1037
MethodType mt1 = mh1.type();
jaroslav@1692
  1038
if (mh0.isVarargsCollector())
jaroslav@1692
  1039
  mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
jaroslav@1692
  1040
return mh1;
jaroslav@1692
  1041
         * }</pre></blockquote>
jaroslav@1692
  1042
         * where {@code defc} is either {@code receiver.getClass()} or a super
jaroslav@1692
  1043
         * type of that class, in which the requested method is accessible
jaroslav@1692
  1044
         * to the lookup class.
jaroslav@1692
  1045
         * (Note that {@code bindTo} does not preserve variable arity.)
jaroslav@1692
  1046
         * @param receiver the object from which the method is accessed
jaroslav@1692
  1047
         * @param name the name of the method
jaroslav@1692
  1048
         * @param type the type of the method, with the receiver argument omitted
jaroslav@1692
  1049
         * @return the desired method handle
jaroslav@1692
  1050
         * @throws NoSuchMethodException if the method does not exist
jaroslav@1692
  1051
         * @throws IllegalAccessException if access checking fails
jaroslav@1692
  1052
         *                                or if the method's variable arity modifier bit
jaroslav@1692
  1053
         *                                is set and {@code asVarargsCollector} fails
jaroslav@1692
  1054
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
  1055
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
  1056
         * @throws NullPointerException if any argument is null
jaroslav@1692
  1057
         * @see MethodHandle#bindTo
jaroslav@1692
  1058
         * @see #findVirtual
jaroslav@1692
  1059
         */
jaroslav@1692
  1060
        public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
jaroslav@1692
  1061
            throw new IllegalStateException();
jaroslav@1692
  1062
        }
jaroslav@1692
  1063
jaroslav@1692
  1064
        /**
jaroslav@1692
  1065
         * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
jaroslav@1692
  1066
         * to <i>m</i>, if the lookup class has permission.
jaroslav@1692
  1067
         * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
jaroslav@1692
  1068
         * If <i>m</i> is virtual, overriding is respected on every call.
jaroslav@1692
  1069
         * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
jaroslav@1692
  1070
         * The type of the method handle will be that of the method,
jaroslav@1692
  1071
         * with the receiver type prepended (but only if it is non-static).
jaroslav@1692
  1072
         * If the method's {@code accessible} flag is not set,
jaroslav@1692
  1073
         * access checking is performed immediately on behalf of the lookup class.
jaroslav@1692
  1074
         * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
jaroslav@1692
  1075
         * <p>
jaroslav@1692
  1076
         * The returned method handle will have
jaroslav@1692
  1077
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
jaroslav@1692
  1078
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
jaroslav@1692
  1079
         * <p>
jaroslav@1692
  1080
         * If <i>m</i> is static, and
jaroslav@1692
  1081
         * if the returned method handle is invoked, the method's class will
jaroslav@1692
  1082
         * be initialized, if it has not already been initialized.
jaroslav@1692
  1083
         * @param m the reflected method
jaroslav@1692
  1084
         * @return a method handle which can invoke the reflected method
jaroslav@1692
  1085
         * @throws IllegalAccessException if access checking fails
jaroslav@1692
  1086
         *                                or if the method's variable arity modifier bit
jaroslav@1692
  1087
         *                                is set and {@code asVarargsCollector} fails
jaroslav@1692
  1088
         * @throws NullPointerException if the argument is null
jaroslav@1692
  1089
         */
jaroslav@1692
  1090
        public MethodHandle unreflect(Method m) throws IllegalAccessException {
jaroslav@1692
  1091
            throw new IllegalStateException();
jaroslav@1692
  1092
        }
jaroslav@1692
  1093
jaroslav@1692
  1094
        /**
jaroslav@1692
  1095
         * Produces a method handle for a reflected method.
jaroslav@1692
  1096
         * It will bypass checks for overriding methods on the receiver,
jaroslav@1692
  1097
         * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
jaroslav@1692
  1098
         * instruction from within the explicitly specified {@code specialCaller}.
jaroslav@1692
  1099
         * The type of the method handle will be that of the method,
jaroslav@1692
  1100
         * with a suitably restricted receiver type prepended.
jaroslav@1692
  1101
         * (The receiver type will be {@code specialCaller} or a subtype.)
jaroslav@1692
  1102
         * If the method's {@code accessible} flag is not set,
jaroslav@1692
  1103
         * access checking is performed immediately on behalf of the lookup class,
jaroslav@1692
  1104
         * as if {@code invokespecial} instruction were being linked.
jaroslav@1692
  1105
         * <p>
jaroslav@1692
  1106
         * Before method resolution,
jaroslav@1692
  1107
         * if the explicitly specified caller class is not identical with the
jaroslav@1692
  1108
         * lookup class, or if this lookup object does not have
jaroslav@1692
  1109
         * <a href="MethodHandles.Lookup.html#privacc">private access</a>
jaroslav@1692
  1110
         * privileges, the access fails.
jaroslav@1692
  1111
         * <p>
jaroslav@1692
  1112
         * The returned method handle will have
jaroslav@1692
  1113
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
jaroslav@1692
  1114
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
jaroslav@1692
  1115
         * @param m the reflected method
jaroslav@1692
  1116
         * @param specialCaller the class nominally calling the method
jaroslav@1692
  1117
         * @return a method handle which can invoke the reflected method
jaroslav@1692
  1118
         * @throws IllegalAccessException if access checking fails
jaroslav@1692
  1119
         *                                or if the method's variable arity modifier bit
jaroslav@1692
  1120
         *                                is set and {@code asVarargsCollector} fails
jaroslav@1692
  1121
         * @throws NullPointerException if any argument is null
jaroslav@1692
  1122
         */
jaroslav@1692
  1123
        public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
jaroslav@1692
  1124
            throw new IllegalStateException();
jaroslav@1692
  1125
        }
jaroslav@1692
  1126
jaroslav@1692
  1127
        /**
jaroslav@1692
  1128
         * Produces a method handle for a reflected constructor.
jaroslav@1692
  1129
         * The type of the method handle will be that of the constructor,
jaroslav@1692
  1130
         * with the return type changed to the declaring class.
jaroslav@1692
  1131
         * The method handle will perform a {@code newInstance} operation,
jaroslav@1692
  1132
         * creating a new instance of the constructor's class on the
jaroslav@1692
  1133
         * arguments passed to the method handle.
jaroslav@1692
  1134
         * <p>
jaroslav@1692
  1135
         * If the constructor's {@code accessible} flag is not set,
jaroslav@1692
  1136
         * access checking is performed immediately on behalf of the lookup class.
jaroslav@1692
  1137
         * <p>
jaroslav@1692
  1138
         * The returned method handle will have
jaroslav@1692
  1139
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
jaroslav@1692
  1140
         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
jaroslav@1692
  1141
         * <p>
jaroslav@1692
  1142
         * If the returned method handle is invoked, the constructor's class will
jaroslav@1692
  1143
         * be initialized, if it has not already been initialized.
jaroslav@1692
  1144
         * @param c the reflected constructor
jaroslav@1692
  1145
         * @return a method handle which can invoke the reflected constructor
jaroslav@1692
  1146
         * @throws IllegalAccessException if access checking fails
jaroslav@1692
  1147
         *                                or if the method's variable arity modifier bit
jaroslav@1692
  1148
         *                                is set and {@code asVarargsCollector} fails
jaroslav@1692
  1149
         * @throws NullPointerException if the argument is null
jaroslav@1692
  1150
         */
jaroslav@1692
  1151
        public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
jaroslav@1692
  1152
            throw new IllegalStateException();
jaroslav@1692
  1153
        }
jaroslav@1692
  1154
jaroslav@1692
  1155
        /**
jaroslav@1692
  1156
         * Produces a method handle giving read access to a reflected field.
jaroslav@1692
  1157
         * The type of the method handle will have a return type of the field's
jaroslav@1692
  1158
         * value type.
jaroslav@1692
  1159
         * If the field is static, the method handle will take no arguments.
jaroslav@1692
  1160
         * Otherwise, its single argument will be the instance containing
jaroslav@1692
  1161
         * the field.
jaroslav@1692
  1162
         * If the field's {@code accessible} flag is not set,
jaroslav@1692
  1163
         * access checking is performed immediately on behalf of the lookup class.
jaroslav@1692
  1164
         * <p>
jaroslav@1692
  1165
         * If the field is static, and
jaroslav@1692
  1166
         * if the returned method handle is invoked, the field's class will
jaroslav@1692
  1167
         * be initialized, if it has not already been initialized.
jaroslav@1692
  1168
         * @param f the reflected field
jaroslav@1692
  1169
         * @return a method handle which can load values from the reflected field
jaroslav@1692
  1170
         * @throws IllegalAccessException if access checking fails
jaroslav@1692
  1171
         * @throws NullPointerException if the argument is null
jaroslav@1692
  1172
         */
jaroslav@1692
  1173
        public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
jaroslav@1692
  1174
            throw new IllegalStateException();
jaroslav@1692
  1175
        }
jaroslav@1692
  1176
jaroslav@1692
  1177
        /**
jaroslav@1692
  1178
         * Produces a method handle giving write access to a reflected field.
jaroslav@1692
  1179
         * The type of the method handle will have a void return type.
jaroslav@1692
  1180
         * If the field is static, the method handle will take a single
jaroslav@1692
  1181
         * argument, of the field's value type, the value to be stored.
jaroslav@1692
  1182
         * Otherwise, the two arguments will be the instance containing
jaroslav@1692
  1183
         * the field, and the value to be stored.
jaroslav@1692
  1184
         * If the field's {@code accessible} flag is not set,
jaroslav@1692
  1185
         * access checking is performed immediately on behalf of the lookup class.
jaroslav@1692
  1186
         * <p>
jaroslav@1692
  1187
         * If the field is static, and
jaroslav@1692
  1188
         * if the returned method handle is invoked, the field's class will
jaroslav@1692
  1189
         * be initialized, if it has not already been initialized.
jaroslav@1692
  1190
         * @param f the reflected field
jaroslav@1692
  1191
         * @return a method handle which can store values into the reflected field
jaroslav@1692
  1192
         * @throws IllegalAccessException if access checking fails
jaroslav@1692
  1193
         * @throws NullPointerException if the argument is null
jaroslav@1692
  1194
         */
jaroslav@1692
  1195
        public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
jaroslav@1692
  1196
            throw new IllegalStateException();
jaroslav@1692
  1197
        }
jaroslav@1692
  1198
jaroslav@1692
  1199
        /**
jaroslav@1692
  1200
         * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
jaroslav@1692
  1201
         * created by this lookup object or a similar one.
jaroslav@1692
  1202
         * Security and access checks are performed to ensure that this lookup object
jaroslav@1692
  1203
         * is capable of reproducing the target method handle.
jaroslav@1692
  1204
         * This means that the cracking may fail if target is a direct method handle
jaroslav@1692
  1205
         * but was created by an unrelated lookup object.
jaroslav@1692
  1206
         * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
jaroslav@1692
  1207
         * and was created by a lookup object for a different class.
jaroslav@1692
  1208
         * @param target a direct method handle to crack into symbolic reference components
jaroslav@1692
  1209
         * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
jaroslav@1692
  1210
         * @exception SecurityException if a security manager is present and it
jaroslav@1692
  1211
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
jaroslav@1692
  1212
         * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
jaroslav@1692
  1213
         * @exception NullPointerException if the target is {@code null}
jaroslav@1692
  1214
         * @see MethodHandleInfo
jaroslav@1692
  1215
         * @since 1.8
jaroslav@1692
  1216
         */
jaroslav@1692
  1217
//        public MethodHandleInfo revealDirect(MethodHandle target) {
jaroslav@1692
  1218
//            throw new IllegalStateException();
jaroslav@1692
  1219
//        }
jaroslav@1692
  1220
    }
jaroslav@1692
  1221
jaroslav@1692
  1222
}