All Downloads are FREE. Search and download functionalities are using the official Maven repository.

java.lang.constant.MethodHandleDesc Maven / Gradle / Ivy

There is a newer version: 17.alpha.0.57
Show newest version
/*
 * 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
 * {@link MethodHandle} constant.
 *
 * @since 12
 */
public sealed interface MethodHandleDesc
        extends ConstantDesc
        permits AsTypeMethodHandleDesc,
                DirectMethodHandleDesc {

    /**
     * Creates a {@linkplain 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 {@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 {@linkplain 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 {@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 {@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 -> MethodTypeDesc.of(fieldType, owner); case SETTER -> MethodTypeDesc.of(CD_void, owner, fieldType); case STATIC_GETTER -> MethodTypeDesc.of(fieldType); case STATIC_SETTER -> MethodTypeDesc.of(CD_void, fieldType); default -> throw new IllegalArgumentException(kind.toString()); }; return new DirectMethodHandleDescImpl(kind, owner, fieldName, mtr); } /** * 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 {@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 {@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 * {@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); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy