< prev index next >

src/java.base/share/classes/java/lang/invoke/MethodType.java

Print this page
rev 52786 : 8210031: implementation for JVM Constants API


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import jdk.internal.vm.annotation.Stable;
  29 import sun.invoke.util.Wrapper;
  30 import java.lang.ref.WeakReference;
  31 import java.lang.ref.Reference;
  32 import java.lang.ref.ReferenceQueue;

  33 import java.util.Arrays;
  34 import java.util.Collections;
  35 import java.util.List;

  36 import java.util.Objects;

  37 import java.util.StringJoiner;
  38 import java.util.concurrent.ConcurrentMap;
  39 import java.util.concurrent.ConcurrentHashMap;




  40 import sun.invoke.util.BytecodeDescriptor;
  41 import static java.lang.invoke.MethodHandleStatics.*;
  42 import sun.invoke.util.VerifyType;




  43 
  44 /**
  45  * A method type represents the arguments and return type accepted and
  46  * returned by a method handle, or the arguments and return type passed
  47  * and expected  by a method handle caller.  Method types must be properly
  48  * matched between a method handle and all its callers,
  49  * and the JVM's operations enforce this matching at, specifically
  50  * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
  51  * and {@link MethodHandle#invoke MethodHandle.invoke}, and during execution
  52  * of {@code invokedynamic} instructions.
  53  * <p>
  54  * The structure is a return type accompanied by any number of parameter types.
  55  * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
  56  * (For ease of exposition, we treat {@code void} as if it were a type.
  57  * In fact, it denotes the absence of a return type.)
  58  * <p>
  59  * All instances of {@code MethodType} are immutable.
  60  * Two instances are completely interchangeable if they compare equal.
  61  * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
  62  * <p>


  74  * {@code MethodType} objects are sometimes derived from bytecode instructions
  75  * such as {@code invokedynamic}, specifically from the type descriptor strings associated
  76  * with the instructions in a class file's constant pool.
  77  * <p>
  78  * Like classes and strings, method types can also be represented directly
  79  * in a class file's constant pool as constants.
  80  * A method type may be loaded by an {@code ldc} instruction which refers
  81  * to a suitable {@code CONSTANT_MethodType} constant pool entry.
  82  * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
  83  * (For full details on method type constants,
  84  * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
  85  * <p>
  86  * When the JVM materializes a {@code MethodType} from a descriptor string,
  87  * all classes named in the descriptor must be accessible, and will be loaded.
  88  * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
  89  * This loading may occur at any time before the {@code MethodType} object is first derived.
  90  * @author John Rose, JSR 292 EG
  91  * @since 1.7
  92  */
  93 public final
  94 class MethodType implements java.io.Serializable {



  95     private static final long serialVersionUID = 292L;  // {rtype, {ptype...}}
  96 
  97     // The rtype and ptypes fields define the structural identity of the method type:
  98     private final @Stable Class<?>   rtype;
  99     private final @Stable Class<?>[] ptypes;
 100 
 101     // The remaining fields are caches of various sorts:
 102     private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
 103     private @Stable MethodType wrapAlt;  // alternative wrapped/unwrapped version
 104     private @Stable Invokers invokers;   // cache of handy higher-order adapters
 105     private @Stable String methodDescriptor;  // cache for toMethodDescriptorString
 106 
 107     /**
 108      * Constructor that performs no copying or validation.
 109      * Should only be called from the factory method makeImpl
 110      */
 111     private MethodType(Class<?> rtype, Class<?>[] ptypes) {
 112         this.rtype = rtype;
 113         this.ptypes = ptypes;
 114     }


1158      * <p>
1159      * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
1160      * Two distinct classes which share a common name but have different class loaders
1161      * will appear identical when viewed within descriptor strings.
1162      * <p>
1163      * This method is included for the benefit of applications that must
1164      * generate bytecodes that process method handles and {@code invokedynamic}.
1165      * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
1166      * because the latter requires a suitable class loader argument.
1167      * @return the bytecode type descriptor representation
1168      */
1169     public String toMethodDescriptorString() {
1170         String desc = methodDescriptor;
1171         if (desc == null) {
1172             desc = BytecodeDescriptor.unparseMethod(this.rtype, this.ptypes);
1173             methodDescriptor = desc;
1174         }
1175         return desc;
1176     }
1177 












1178     /*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
1179         return BytecodeDescriptor.unparse(cls);





















1180     }
1181 
1182     /// Serialization.
1183 
1184     /**
1185      * There are no serializable fields for {@code MethodType}.
1186      */
1187     private static final java.io.ObjectStreamField[] serialPersistentFields = { };
1188 
1189     /**
1190      * Save the {@code MethodType} instance to a stream.
1191      *
1192      * @serialData
1193      * For portability, the serialized format does not refer to named fields.
1194      * Instead, the return type and parameter type arrays are written directly
1195      * from the {@code writeObject} method, using two calls to {@code s.writeObject}
1196      * as follows:
1197      * <blockquote><pre>{@code
1198 s.writeObject(this.returnType());
1199 s.writeObject(this.parameterArray());




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import java.lang.constant.ClassDesc;
  29 import java.lang.constant.Constable;
  30 import java.lang.constant.MethodTypeDesc;
  31 import java.lang.ref.Reference;
  32 import java.lang.ref.ReferenceQueue;
  33 import java.lang.ref.WeakReference;
  34 import java.util.Arrays;
  35 import java.util.Collections;
  36 import java.util.List;
  37 import java.util.NoSuchElementException;
  38 import java.util.Objects;
  39 import java.util.Optional;
  40 import java.util.StringJoiner;

  41 import java.util.concurrent.ConcurrentHashMap;
  42 import java.util.concurrent.ConcurrentMap;
  43 import java.util.stream.Stream;
  44 
  45 import jdk.internal.vm.annotation.Stable;
  46 import sun.invoke.util.BytecodeDescriptor;

  47 import sun.invoke.util.VerifyType;
  48 import sun.invoke.util.Wrapper;
  49 
  50 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  51 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
  52 
  53 /**
  54  * A method type represents the arguments and return type accepted and
  55  * returned by a method handle, or the arguments and return type passed
  56  * and expected  by a method handle caller.  Method types must be properly
  57  * matched between a method handle and all its callers,
  58  * and the JVM's operations enforce this matching at, specifically
  59  * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
  60  * and {@link MethodHandle#invoke MethodHandle.invoke}, and during execution
  61  * of {@code invokedynamic} instructions.
  62  * <p>
  63  * The structure is a return type accompanied by any number of parameter types.
  64  * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
  65  * (For ease of exposition, we treat {@code void} as if it were a type.
  66  * In fact, it denotes the absence of a return type.)
  67  * <p>
  68  * All instances of {@code MethodType} are immutable.
  69  * Two instances are completely interchangeable if they compare equal.
  70  * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
  71  * <p>


  83  * {@code MethodType} objects are sometimes derived from bytecode instructions
  84  * such as {@code invokedynamic}, specifically from the type descriptor strings associated
  85  * with the instructions in a class file's constant pool.
  86  * <p>
  87  * Like classes and strings, method types can also be represented directly
  88  * in a class file's constant pool as constants.
  89  * A method type may be loaded by an {@code ldc} instruction which refers
  90  * to a suitable {@code CONSTANT_MethodType} constant pool entry.
  91  * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
  92  * (For full details on method type constants,
  93  * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
  94  * <p>
  95  * When the JVM materializes a {@code MethodType} from a descriptor string,
  96  * all classes named in the descriptor must be accessible, and will be loaded.
  97  * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
  98  * This loading may occur at any time before the {@code MethodType} object is first derived.
  99  * @author John Rose, JSR 292 EG
 100  * @since 1.7
 101  */
 102 public final
 103 class MethodType
 104         implements Constable,
 105                    TypeDescriptor.OfMethod<Class<?>, MethodType>,
 106                    java.io.Serializable {
 107     private static final long serialVersionUID = 292L;  // {rtype, {ptype...}}
 108 
 109     // The rtype and ptypes fields define the structural identity of the method type:
 110     private final @Stable Class<?>   rtype;
 111     private final @Stable Class<?>[] ptypes;
 112 
 113     // The remaining fields are caches of various sorts:
 114     private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
 115     private @Stable MethodType wrapAlt;  // alternative wrapped/unwrapped version
 116     private @Stable Invokers invokers;   // cache of handy higher-order adapters
 117     private @Stable String methodDescriptor;  // cache for toMethodDescriptorString
 118 
 119     /**
 120      * Constructor that performs no copying or validation.
 121      * Should only be called from the factory method makeImpl
 122      */
 123     private MethodType(Class<?> rtype, Class<?>[] ptypes) {
 124         this.rtype = rtype;
 125         this.ptypes = ptypes;
 126     }


1170      * <p>
1171      * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
1172      * Two distinct classes which share a common name but have different class loaders
1173      * will appear identical when viewed within descriptor strings.
1174      * <p>
1175      * This method is included for the benefit of applications that must
1176      * generate bytecodes that process method handles and {@code invokedynamic}.
1177      * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
1178      * because the latter requires a suitable class loader argument.
1179      * @return the bytecode type descriptor representation
1180      */
1181     public String toMethodDescriptorString() {
1182         String desc = methodDescriptor;
1183         if (desc == null) {
1184             desc = BytecodeDescriptor.unparseMethod(this.rtype, this.ptypes);
1185             methodDescriptor = desc;
1186         }
1187         return desc;
1188     }
1189 
1190     /**
1191      * Return a field type descriptor string for this type
1192      *
1193      * @return the descriptor string
1194      * @jvms 4.3.2 Field Descriptors
1195      * @since 12
1196      */
1197     @Override
1198     public String descriptorString() {
1199         return toMethodDescriptorString();
1200     }
1201 
1202     /*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
1203         return BytecodeDescriptor.unparse(cls);
1204     }
1205 
1206     /**
1207      * Return a nominal descriptor for this instance, if one can be
1208      * constructed, or an empty {@link Optional} if one cannot be.
1209      *
1210      * @return An {@link Optional} containing the resulting nominal descriptor,
1211      * or an empty {@link Optional} if one cannot be constructed.
1212      * @since 12
1213      */
1214     @Override
1215     public Optional<MethodTypeDesc> describeConstable() {
1216         try {
1217             return Optional.of(MethodTypeDesc.of(returnType().describeConstable().orElseThrow(),
1218                                                  Stream.of(parameterArray())
1219                                                       .map(p -> p.describeConstable().orElseThrow())
1220                                                       .toArray(ClassDesc[]::new)));
1221         }
1222         catch (NoSuchElementException e) {
1223             return Optional.empty();
1224         }
1225     }
1226 
1227     /// Serialization.
1228 
1229     /**
1230      * There are no serializable fields for {@code MethodType}.
1231      */
1232     private static final java.io.ObjectStreamField[] serialPersistentFields = { };
1233 
1234     /**
1235      * Save the {@code MethodType} instance to a stream.
1236      *
1237      * @serialData
1238      * For portability, the serialized format does not refer to named fields.
1239      * Instead, the return type and parameter type arrays are written directly
1240      * from the {@code writeObject} method, using two calls to {@code s.writeObject}
1241      * as follows:
1242      * <blockquote><pre>{@code
1243 s.writeObject(this.returnType());
1244 s.writeObject(this.parameterArray());


< prev index next >