APIdia Launch Partner
Top Description Inners Fields Constructors Methods
java.lang.invoke

public final Class MethodHandleProxies

extends Object
Class Inheritance
Imports
java.lang.constant.ClassDesc, .MethodTypeDesc, java.lang.invoke.MethodHandles.Lookup, java.lang.module.ModuleDescriptor, java.lang.ref.WeakReference, java.lang.reflect.Method, .Modifier, .UndeclaredThrowableException, java.util.ArrayList, .Arrays, .HashSet, .List, .Objects, .Set, java.util.concurrent.atomic.AtomicInteger, java.util.stream.Stream, jdk.internal.access.JavaLangReflectAccess, .SharedSecrets, java.lang.classfile.ClassHierarchyResolver, .ClassFile, .CodeBuilder, .TypeKind, jdk.internal.constant.ConstantUtils, jdk.internal.loader.ClassLoaders, jdk.internal.module.Modules, jdk.internal.util.ClassFileDumper, .ReferencedKeySet

This class consists exclusively of static methods that help adapt method handles to other JVM types, such as interfaces.
Since
1.7

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static record
private static class

Field Summary

Modifier and TypeField and Description
private static final ClassDesc
private static final ClassDesc
private static final AtomicInteger
private static final List<ClassDesc>
private static final ClassFileDumper
private static final String
private static final JavaLangReflectAccess
private static final MethodType
private static final MethodType
private static final MethodType
private static final MethodTypeDesc
private static final MethodTypeDesc
private static final MethodTypeDesc
private static final MethodTypeDesc
private static final MethodTypeDesc
private static final MethodTypeDesc
private static final MethodTypeDesc
private static final MethodTypeDesc
private static final ClassValue<MethodHandleProxies.WeakReferenceHolder<Class<?>>>
private static final String
private static final String
private static final Set<Class<?>>

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
private static void
addElementType(Set<Class<?>> types, Class<?> cls)

private static void
addElementTypes(Set<Class<?>> types, Class<?>... classes)

public static <
the desired type of the wrapper, a single-method interface
T
>
T

Returns:

a correctly-typed wrapper for the given target
asInterfaceInstance
(final Class<T>
a class object representing T
intfc
,
final MethodHandle
the method handle to invoke from the wrapper
target
)

Produces an instance of the given single-method interface which redirects its calls to the given method handle.

private static MethodHandle
bindCaller(MethodHandle target, Class<?> hostClass)

private static byte[]

Returns:

the bytes of the implementation classes
createTemplate
(ClassLoader loader, ClassDesc proxyDesc, ClassDesc
the given interface
ifaceDesc
,
String
the name of the single abstract method
methodName
,
List<MethodHandleProxies.MethodInfo>
the information for implementation methods
methods
)

Creates an implementation class file for a given interface.

private static void
ensureAccess(Module target, Class<?> c)

private static Class<?>
getProxyClass(Class<?> intfc)

private static boolean
public static boolean

Returns:

true if the reference is not null and points to an object produced by asInterfaceInstance
isWrapperInstance
(Object
any reference
x
)

Determines if the given object was produced by a call to asInterfaceInstance.

private static Module
newDynamicModule(ClassLoader ld, Set<Class<?>> types)

Create a dynamic module defined to the given class loader and has access to the given types.

private static Class<?>
newProxyClass(Class<?> intfc)

private static String
public static MethodHandle

Returns:

a method handle implementing the unique method
wrapperInstanceTarget
(Object
any reference
x
)

Produces or recovers a target method handle which is behaviorally equivalent to the unique method of this wrapper instance.

public static Class<?>

Returns:

the single-method interface type for which the wrapper was created
wrapperInstanceType
(Object
any reference
x
)

Recovers the unique single-method interface type for which this wrapper instance was created.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

CD_IllegalAccessExceptionback to summary
private static final ClassDesc CD_IllegalAccessException
CD_UndeclaredThrowableExceptionback to summary
private static final ClassDesc CD_UndeclaredThrowableException
counterback to summary
private static final AtomicInteger counter
DEFAULT_RETHROWSback to summary
private static final List<ClassDesc> DEFAULT_RETHROWS
DUMPERback to summary
private static final ClassFileDumper DUMPER
ENSURE_ORIGINAL_LOOKUPback to summary
private static final String ENSURE_ORIGINAL_LOOKUP
JLRAback to summary
private static final JavaLangReflectAccess JLRA
MT_MethodHandle_Objectback to summary
private static final MethodType MT_MethodHandle_Object
MT_Object_Lookup_MethodHandle_MethodHandleback to summary
private static final MethodType MT_Object_Lookup_MethodHandle_MethodHandle
MT_void_Lookup_MethodHandle_MethodHandleback to summary
private static final MethodType MT_void_Lookup_MethodHandle_MethodHandle
MTD_Classback to summary
private static final MethodTypeDesc MTD_Class
MTD_intback to summary
private static final MethodTypeDesc MTD_int
MTD_MethodHandle_MethodTypeback to summary
private static final MethodTypeDesc MTD_MethodHandle_MethodType
MTD_Stringback to summary
private static final MethodTypeDesc MTD_String
MTD_void_Lookupback to summary
private static final MethodTypeDesc MTD_void_Lookup
MTD_void_Lookup_MethodHandle_MethodHandleback to summary
private static final MethodTypeDesc MTD_void_Lookup_MethodHandle_MethodHandle
MTD_void_Stringback to summary
private static final MethodTypeDesc MTD_void_String
MTD_void_Throwableback to summary
private static final MethodTypeDesc MTD_void_Throwable
PROXIESback to summary
private static final ClassValue<MethodHandleProxies.WeakReferenceHolder<Class<?>>> PROXIES
TARGET_NAMEback to summary
private static final String TARGET_NAME
TYPE_NAMEback to summary
private static final String TYPE_NAME
WRAPPER_TYPESback to summary
private static final Set<Class<?>> WRAPPER_TYPES

Constructor Detail

MethodHandleProxiesback to summary
private MethodHandleProxies()

Method Detail

addElementTypeback to summary
private static void addElementType(Set<Class<?>> types, Class<?> cls)
addElementTypesback to summary
private static void addElementTypes(Set<Class<?>> types, Class<?>... classes)
asInterfaceInstanceback to summary
public static <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target)

Produces an instance of the given single-method interface which redirects its calls to the given method handle.

A single-method interface is an interface which declares a uniquely named method. When determining the uniquely named method of a single-method interface, the public Object methods (toString, equals, hashCode) are disregarded as are any default (non-abstract) methods. For example, java.util.Comparator is a single-method interface, even though it re-declares the Object.equals method and also declares default methods, such as Comparator.reverse.

The interface must be public, not hidden, and not sealed. No additional access checks are performed.

The resulting instance of the required type will respond to invocation of the type's uniquely named method by calling the given target on the incoming arguments, and returning or throwing whatever the target returns or throws. The invocation will be as if by target.invoke. The target's type will be checked before the instance is created, as if by a call to asType, which may result in a WrongMethodTypeException.

The uniquely named method is allowed to be multiply declared, with distinct type descriptors. (E.g., it can be overloaded, or can possess bridge methods.) All such declarations are connected directly to the target method handle. Argument and return types are adjusted by asType for each individual declaration.

The wrapper instance will implement the requested interface and its super-types, but no other single-method interfaces. This means that the instance will not unexpectedly pass an instanceof test for any unrequested type.

Implementation Note

Therefore, each instance must implement a unique single-method interface. Implementations may not bundle together multiple single-method interfaces onto single implementation classes in the style of java.desktop/java.awt.AWTEventMulticaster.

The method handle may throw an undeclared exception, which means any checked exception (or other checked throwable) not declared by the requested type's single abstract method. If this happens, the throwable will be wrapped in an instance of UndeclaredThrowableException and thrown in that wrapped form.

Like Integer.valueOf, asInterfaceInstance is a factory method whose results are defined by their behavior. It is not guaranteed to return a new instance for every call.

Because of the possibility of bridge methods and other corner cases, the interface may also have several abstract methods with the same name but having distinct descriptors (types of returns and parameters). In this case, all the methods are bound in common to the one given target. The type check and effective asType conversion is applied to each method type descriptor, and all abstract methods are bound to the target in common. Beyond this type check, no further checks are made to determine that the abstract methods are related in any way.

Future versions of this API may accept additional types, such as abstract classes with single abstract methods. Future versions of this API may also equip wrapper instances with one or more additional public "marker" interfaces.

Parameters
<T>
the desired type of the wrapper, a single-method interface
intfc:Class<T>

a class object representing T

target:MethodHandle

the method handle to invoke from the wrapper

Returns:T

a correctly-typed wrapper for the given target

Annotations
@SuppressWarnings:doclint:reference
Exceptions
NullPointerException:
if either argument is null
IllegalArgumentException:
if the intfc is not a valid argument to this method
WrongMethodTypeException:
if the target cannot be converted to the type required by the requested interface
bindCallerback to summary
private static MethodHandle bindCaller(MethodHandle target, Class<?> hostClass)
createTemplateback to summary
private static byte[] createTemplate(ClassLoader loader, ClassDesc proxyDesc, ClassDesc ifaceDesc, String methodName, List<MethodHandleProxies.MethodInfo> methods)

Creates an implementation class file for a given interface. One implementation class is defined for each interface.

Parameters
ifaceDesc:ClassDesc

the given interface

methodName:String

the name of the single abstract method

methods:List<MethodHandleProxies.MethodInfo>

the information for implementation methods

Returns:byte[]

the bytes of the implementation classes

ensureAccessback to summary
private static void ensureAccess(Module target, Class<?> c)
getProxyClassback to summary
private static Class<?> getProxyClass(Class<?> intfc)
isObjectMethodback to summary
private static boolean isObjectMethod(Method m)
isWrapperInstanceback to summary
public static boolean isWrapperInstance(Object x)

Determines if the given object was produced by a call to asInterfaceInstance.

Parameters
x:Object

any reference

Returns:boolean

true if the reference is not null and points to an object produced by asInterfaceInstance

newDynamicModuleback to summary
private static Module newDynamicModule(ClassLoader ld, Set<Class<?>> types)

Create a dynamic module defined to the given class loader and has access to the given types.

The dynamic module contains only one single package named the same as the name of the dynamic module. It's not exported or open.

newProxyClassback to summary
private static Class<?> newProxyClass(Class<?> intfc)
nextModuleNameback to summary
private static String nextModuleName()
wrapperInstanceTargetback to summary
public static MethodHandle wrapperInstanceTarget(Object x)

Produces or recovers a target method handle which is behaviorally equivalent to the unique method of this wrapper instance. The object x must have been produced by a call to asInterfaceInstance. This requirement may be tested via isWrapperInstance.

Parameters
x:Object

any reference

Returns:MethodHandle

a method handle implementing the unique method

Exceptions
IllegalArgumentException:
if the reference x is not to a wrapper instance
wrapperInstanceTypeback to summary
public static Class<?> wrapperInstanceType(Object x)

Recovers the unique single-method interface type for which this wrapper instance was created. The object x must have been produced by a call to asInterfaceInstance. This requirement may be tested via isWrapperInstance.

Parameters
x:Object

any reference

Returns:Class<?>

the single-method interface type for which the wrapper was created

Exceptions
IllegalArgumentException:
if the reference x is not to a wrapper instance
java.lang.invoke back to summary

private final Record MethodHandleProxies.MethodInfo

extends Record
Class Inheritance
Record Components
desc:MethodTypeDesc 
thrown:List<ClassDesc> 
fieldName:String 

Field Summary

Modifier and TypeField and Description
private final MethodTypeDesc
desc

Record Component accessed by desc().

private final String
fieldName

Record Component accessed by fieldName().

private final List<ClassDesc>
thrown

Record Component accessed by thrown().

Constructor Summary

AccessConstructor and Description
private
MethodInfo(MethodTypeDesc desc, List<ClassDesc> thrown, String fieldName)

Method Summary

Modifier and TypeMethod and Description
public MethodTypeDesc
desc()

Record Component getter of desc.

public final boolean
equals(Object o)

Implements abstract java.lang.Record.equals.

Indicates whether some other object is "equal to" this one.

public String
fieldName()

Record Component getter of fieldName.

public final int
hashCode()

Implements abstract java.lang.Record.hashCode.

Returns a hash code value for the record.

public List<ClassDesc>
thrown()

Record Component getter of thrown.

public final String
toString()

Implements abstract java.lang.Record.toString.

Returns a string representation of the record.

Field Detail

descback to summary
private final MethodTypeDesc desc

Record Component accessed by desc().

fieldNameback to summary
private final String fieldName

Record Component accessed by fieldName().

thrownback to summary
private final List<ClassDesc> thrown

Record Component accessed by thrown().

Constructor Detail

MethodInfoback to summary
private MethodInfo(MethodTypeDesc desc, List<ClassDesc> thrown, String fieldName)

Method Detail

descback to summary
public MethodTypeDesc desc()

Record Component getter of desc.

equalsback to summary
public final boolean equals(Object o)

Implements abstract java.lang.Record.equals.

Doc from java.lang.Record.equals.

Indicates whether some other object is "equal to" this one. In addition to the general contract of Object.equals, record classes must further obey the invariant that when a record instance is "copied" by passing the result of the record component accessor methods to the canonical constructor, as follows:

    R copy = new R(r.c1(), r.c2(), ..., r.cn());
then it must be the case that r.equals(copy).
fieldNameback to summary
public String fieldName()

Record Component getter of fieldName.

hashCodeback to summary
public final int hashCode()

Implements abstract java.lang.Record.hashCode.

Doc from java.lang.Record.hashCode.

Returns a hash code value for the record. Obeys the general contract of Object.hashCode. For records, hashing behavior is constrained by the refined contract of Record.equals, so that any two records created from the same components must have the same hash code.

thrownback to summary
public List<ClassDesc> thrown()

Record Component getter of thrown.

toStringback to summary
public final String toString()

Implements abstract java.lang.Record.toString.

Doc from java.lang.Record.toString.

Returns a string representation of the record. In accordance with the general contract of Object#toString(), the toString method returns a string that "textually represents" this record. The result should be a concise but informative representation that is easy for a person to read.

In addition to this general contract, record classes must further participate in the invariant that any two records which are equal must produce equal strings. This invariant is necessarily relaxed in the rare case where corresponding equal component values might fail to produce equal strings for themselves.

java.lang.invoke back to summary

private final Class MethodHandleProxies.WeakReferenceHolder<T>

extends Object
Class Inheritance

Field Summary

Modifier and TypeField and Description
private volatile WeakReference<T>

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
pack-priv T
get()

pack-priv void
set(T value)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

refback to summary
private volatile WeakReference<T> ref

Constructor Detail

WeakReferenceHolderback to summary
pack-priv WeakReferenceHolder(T value)

Method Detail

getback to summary
pack-priv T get()
setback to summary
pack-priv void set(T value)