/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.constant;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import static java.lang.constant.ConstantDescs.CD_void;
import static java.lang.constant.DirectMethodHandleDesc.Kind.CONSTRUCTOR;
A nominal descriptor for a MethodHandle
constant. API Note: In the future, if the Java language permits, MethodHandleDesc may become a sealed
interface, which would prohibit subclassing except by explicitly permitted types. Non-platform classes should not implement MethodHandleDesc directly. Since: 12
/**
* A <a href="package-summary.html#nominal">nominal descriptor</a> for a
* {@link MethodHandle} constant.
*
* @apiNote In the future, if the Java language permits, {@linkplain MethodHandleDesc}
* may become a {@code sealed} interface, which would prohibit subclassing except
* by explicitly permitted types. Non-platform classes should not implement
* {@linkplain MethodHandleDesc} directly.
*
* @since 12
*/
public interface MethodHandleDesc
extends ConstantDesc {
Creates a MethodHandleDesc corresponding to an invocation of a declared method, invocation of a constructor, or access to a field. The lookup descriptor string has the same format as for the various variants of CONSTANT_MethodHandle_info
and for the lookup methods on Lookup
. For a method or constructor invocation, it is interpreted as a method type descriptor; for field access, it is interpreted as a field descriptor. If kind
is CONSTRUCTOR
, the name
parameter is ignored and the return type of the lookup descriptor must be void
. If kind
corresponds to a virtual method invocation, the lookup type includes the method parameters but not the receiver type.
Params: - kind – The kind of method handle to be described
- owner – a
ClassDesc
describing the class containing the method, constructor, or field - name – the unqualified name of the method or field (ignored if
kind
is CONSTRUCTOR
) - lookupDescriptor – a method descriptor string the lookup type,
if the request is for a method invocation, or
describing the invocation type, if the request is
for a field or constructor
Throws: - NullPointerException – if any of the non-ignored arguments are null
- IllegalArgumentException – if the descriptor string is not a valid
method or field descriptor
Returns: the MethodHandleDesc @jvms 4.4.8 The CONSTANT_MethodHandle_info Structure @jvms 4.2.2 Unqualified Names @jvms 4.3.2 Field Descriptors @jvms 4.3.3 Method Descriptors
/**
* Creates a {@linkplain MethodHandleDesc} corresponding to an invocation of a
* declared method, invocation of a constructor, or access to a field.
*
* <p>The lookup descriptor string has the same format as for the various
* variants of {@code CONSTANT_MethodHandle_info} and for the lookup
* methods on {@link MethodHandles.Lookup}. For a method or constructor
* invocation, it is interpreted as a method type descriptor; for field
* access, it is interpreted as a field descriptor. If {@code kind} is
* {@code CONSTRUCTOR}, the {@code name} parameter is ignored and the return
* type of the lookup descriptor must be {@code void}. If {@code kind}
* corresponds to a virtual method invocation, the lookup type includes the
* method parameters but not the receiver type.
*
* @param kind The kind of method handle to be described
* @param owner a {@link ClassDesc} describing the class containing the
* method, constructor, or field
* @param name the unqualified name of the method or field (ignored if
* {@code kind} is {@code CONSTRUCTOR})
* @param lookupDescriptor a method descriptor string the lookup type,
* if the request is for a method invocation, or
* describing the invocation type, if the request is
* for a field or constructor
* @return the {@linkplain MethodHandleDesc}
* @throws NullPointerException if any of the non-ignored arguments are null
* @throws IllegalArgumentException if the descriptor string is not a valid
* method or field descriptor
* @jvms 4.4.8 The CONSTANT_MethodHandle_info Structure
* @jvms 4.2.2 Unqualified Names
* @jvms 4.3.2 Field Descriptors
* @jvms 4.3.3 Method Descriptors
*/
static DirectMethodHandleDesc of(DirectMethodHandleDesc.Kind kind,
ClassDesc owner,
String name,
String lookupDescriptor) {
switch (kind) {
case GETTER:
case SETTER:
case STATIC_GETTER:
case STATIC_SETTER:
return ofField(kind, owner, name, ClassDesc.ofDescriptor(lookupDescriptor));
default:
return new DirectMethodHandleDescImpl(kind, owner, name, MethodTypeDesc.ofDescriptor(lookupDescriptor));
}
}
Creates a MethodHandleDesc corresponding to an invocation of a declared method or constructor. The lookup descriptor string has the same format as for the lookup methods on Lookup
. If kind
is CONSTRUCTOR
, the name is ignored and the return type of the lookup type must be void
. If kind
corresponds to a virtual method invocation, the lookup type includes the method parameters but not the receiver type.
Params: - kind – The kind of method handle to be described; must be one of
SPECIAL, VIRTUAL, STATIC, INTERFACE_SPECIAL,
INTERFACE_VIRTUAL, INTERFACE_STATIC, CONSTRUCTOR
- owner – a
ClassDesc
describing the class containing the method or constructor - name – the unqualified name of the method (ignored if
kind
is CONSTRUCTOR
) - lookupMethodType – a
MethodTypeDesc
describing the lookup type
Throws: - NullPointerException – if any non-ignored arguments are null
- IllegalArgumentException – if the
name
has the incorrect format, or the kind is invalid
Returns: the MethodHandleDesc @jvms 4.2.2 Unqualified Names
/**
* Creates a {@linkplain MethodHandleDesc} corresponding to an invocation of a
* declared method or constructor.
*
* <p>The lookup descriptor string has the same format as for the lookup
* methods on {@link MethodHandles.Lookup}. If {@code kind} is
* {@code CONSTRUCTOR}, the name is ignored and the return type of the lookup
* type must be {@code void}. If {@code kind} corresponds to a virtual method
* invocation, the lookup type includes the method parameters but not the
* receiver type.
*
* @param kind The kind of method handle to be described; must be one of
* {@code SPECIAL, VIRTUAL, STATIC, INTERFACE_SPECIAL,
* INTERFACE_VIRTUAL, INTERFACE_STATIC, CONSTRUCTOR}
* @param owner a {@link ClassDesc} describing the class containing the
* method or constructor
* @param name the unqualified name of the method (ignored if {@code kind}
* is {@code CONSTRUCTOR})
* @param lookupMethodType a {@link MethodTypeDesc} describing the lookup type
* @return the {@linkplain MethodHandleDesc}
* @throws NullPointerException if any non-ignored arguments are null
* @throws IllegalArgumentException if the {@code name} has the incorrect
* format, or the kind is invalid
* @jvms 4.2.2 Unqualified Names
*/
static DirectMethodHandleDesc ofMethod(DirectMethodHandleDesc.Kind kind,
ClassDesc owner,
String name,
MethodTypeDesc lookupMethodType) {
switch (kind) {
case GETTER:
case SETTER:
case STATIC_GETTER:
case STATIC_SETTER:
throw new IllegalArgumentException(kind.toString());
case VIRTUAL:
case SPECIAL:
case INTERFACE_VIRTUAL:
case INTERFACE_SPECIAL:
case INTERFACE_STATIC:
case STATIC:
case CONSTRUCTOR:
return new DirectMethodHandleDescImpl(kind, owner, name, lookupMethodType);
default:
throw new IllegalArgumentException(kind.toString());
}
}
Creates a MethodHandleDesc corresponding to a method handle that accesses a field. Params: Throws: - NullPointerException – if any of the arguments are null
- IllegalArgumentException – if the
kind
is not one of the valid values or if the field name is not valid
Returns: the MethodHandleDesc @jvms 4.2.2 Unqualified Names
/**
* Creates a {@linkplain MethodHandleDesc} corresponding to a method handle
* that accesses a field.
*
* @param kind the kind of the method handle to be described; must be one of {@code GETTER},
* {@code SETTER}, {@code STATIC_GETTER}, or {@code STATIC_SETTER}
* @param owner a {@link ClassDesc} describing the class containing the field
* @param fieldName the unqualified name of the field
* @param fieldType a {@link ClassDesc} describing the type of the field
* @return the {@linkplain MethodHandleDesc}
* @throws NullPointerException if any of the arguments are null
* @throws IllegalArgumentException if the {@code kind} is not one of the
* valid values or if the field name is not valid
* @jvms 4.2.2 Unqualified Names
*/
static DirectMethodHandleDesc ofField(DirectMethodHandleDesc.Kind kind,
ClassDesc owner,
String fieldName,
ClassDesc fieldType) {
MethodTypeDesc mtr;
switch (kind) {
case GETTER: mtr = MethodTypeDesc.of(fieldType, owner); break;
case SETTER: mtr = MethodTypeDesc.of(CD_void, owner, fieldType); break;
case STATIC_GETTER: mtr = MethodTypeDesc.of(fieldType); break;
case STATIC_SETTER: mtr = MethodTypeDesc.of(CD_void, fieldType); break;
default:
throw new IllegalArgumentException(kind.toString());
}
return new DirectMethodHandleDescImpl(kind, owner, fieldName, mtr);
}
Returns a MethodHandleDesc corresponding to invocation of a constructor Params: Throws: - NullPointerException – if any argument or its contents is
null
Returns: the MethodHandleDesc
/**
* Returns a {@linkplain MethodHandleDesc} corresponding to invocation of a constructor
*
* @param owner a {@link ClassDesc} describing the class containing the
* constructor
* @param paramTypes {@link ClassDesc}s describing the parameter types of
* the constructor
* @return the {@linkplain MethodHandleDesc}
* @throws NullPointerException if any argument or its contents is {@code null}
*/
static DirectMethodHandleDesc ofConstructor(ClassDesc owner,
ClassDesc... paramTypes) {
return MethodHandleDesc.ofMethod(CONSTRUCTOR, owner, ConstantDescs.DEFAULT_NAME,
MethodTypeDesc.of(CD_void, paramTypes));
}
Returns a MethodHandleDesc that describes this method handle adapted to a different type, as if by MethodHandle.asType(MethodType)
. Params: - type – a
MethodHandleDesc
describing the new method type
Throws: - NullPointerException – if the argument is
null
Returns: a MethodHandleDesc for the adapted method handle
/**
* Returns a {@linkplain MethodHandleDesc} that describes this method handle
* adapted to a different type, as if by {@link MethodHandle#asType(MethodType)}.
*
* @param type a {@link MethodHandleDesc} describing the new method type
* @return a {@linkplain MethodHandleDesc} for the adapted method handle
* @throws NullPointerException if the argument is {@code null}
*/
default MethodHandleDesc asType(MethodTypeDesc type) {
return (invocationType().equals(type)) ? this : new AsTypeMethodHandleDesc(this, type);
}
Returns a MethodTypeDesc
describing the invocation type of the method handle described by this nominal descriptor. The invocation type describes the full set of stack values that are consumed by the invocation (including the receiver, if any). Returns: a MethodHandleDesc describing the method handle type
/**
* Returns a {@link MethodTypeDesc} describing the invocation type of the
* method handle described by this nominal descriptor. The invocation type
* describes the full set of stack values that are consumed by the invocation
* (including the receiver, if any).
*
* @return a {@linkplain MethodHandleDesc} describing the method handle type
*/
MethodTypeDesc invocationType();
Compares the specified object with this descriptor for equality. Returns true
if and only if the specified object is also a MethodHandleDesc, and both encode the same nominal description of a method handle. Params: - o – the other object
Returns: whether this descriptor is equal to the other object
/**
* Compares the specified object with this descriptor for equality. Returns
* {@code true} if and only if the specified object is also a
* {@linkplain MethodHandleDesc}, and both encode the same nominal description
* of a method handle.
*
* @param o the other object
* @return whether this descriptor is equal to the other object
*/
boolean equals(Object o);
}