< prev index next >

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

Print this page

  1 /*
  2  * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  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.constant.ClassOrInterfaceDescImpl;

 29 import jdk.internal.misc.CDS;
 30 import jdk.internal.util.ClassFileDumper;
 31 import sun.invoke.util.VerifyAccess;
 32 
 33 import java.io.Serializable;
 34 import java.lang.classfile.ClassBuilder;
 35 import java.lang.classfile.ClassFile;
 36 import java.lang.classfile.CodeBuilder;
 37 import java.lang.classfile.MethodBuilder;
 38 import java.lang.classfile.Opcode;
 39 import java.lang.classfile.TypeKind;
 40 import java.lang.constant.ClassDesc;
 41 import java.lang.constant.MethodTypeDesc;

 42 import java.lang.reflect.Modifier;
 43 import java.util.LinkedHashSet;
 44 import java.util.List;
 45 import java.util.Set;
 46 import java.util.function.Consumer;
 47 
 48 import static java.lang.classfile.ClassFile.*;
 49 import java.lang.classfile.attribute.ExceptionsAttribute;
 50 import java.lang.classfile.constantpool.ClassEntry;
 51 import java.lang.classfile.constantpool.ConstantPoolBuilder;
 52 
 53 import static java.lang.constant.ConstantDescs.*;
 54 import static java.lang.invoke.MethodHandleNatives.Constants.NESTMATE_CLASS;
 55 import static java.lang.invoke.MethodHandleNatives.Constants.STRONG_LOADER_LINK;
 56 import jdk.internal.constant.ConstantUtils;
 57 import jdk.internal.constant.MethodTypeDescImpl;
 58 import jdk.internal.vm.annotation.Stable;
 59 import sun.invoke.util.Wrapper;
 60 
 61 /**

293     private Class<?> generateInnerClass() throws LambdaConversionException {
294         List<ClassDesc> interfaces;
295         ClassDesc interfaceDesc = classDesc(interfaceClass);
296         boolean accidentallySerializable = !isSerializable && Serializable.class.isAssignableFrom(interfaceClass);
297         if (altInterfaces.length == 0) {
298             interfaces = List.of(interfaceDesc);
299         } else {
300             // Assure no duplicate interfaces (ClassFormatError)
301             Set<ClassDesc> itfs = LinkedHashSet.newLinkedHashSet(altInterfaces.length + 1);
302             itfs.add(interfaceDesc);
303             for (Class<?> i : altInterfaces) {
304                 itfs.add(classDesc(i));
305                 accidentallySerializable |= !isSerializable && Serializable.class.isAssignableFrom(i);
306             }
307             interfaces = List.copyOf(itfs);
308         }
309         final boolean finalAccidentallySerializable = accidentallySerializable;
310         final byte[] classBytes = ClassFile.of().build(lambdaClassEntry, pool, new Consumer<ClassBuilder>() {
311             @Override
312             public void accept(ClassBuilder clb) {
313                 clb.withFlags(ACC_SUPER | ACC_FINAL | ACC_SYNTHETIC)

314                    .withInterfaceSymbols(interfaces);


315                 // Generate final fields to be filled in by constructor
316                 for (int i = 0; i < argDescs.length; i++) {
317                     clb.withField(argName(i), argDescs[i], ACC_PRIVATE | ACC_FINAL);
318                 }
319 
320                 generateConstructor(clb);
321 
322                 if (factoryType.parameterCount() == 0 && disableEagerInitialization) {
323                     generateClassInitializer(clb);
324                 }
325 
326                 // Forward the SAM method
327                 clb.withMethodBody(interfaceMethodName,
328                         methodDesc(interfaceMethodType),
329                         ACC_PUBLIC,
330                         forwardingMethod(interfaceMethodType));
331 
332                 // Forward the bridges
333                 if (altMethods != null) {
334                     for (MethodType mt : altMethods) {

  1 /*
  2  * Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  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.constant.ClassOrInterfaceDescImpl;
 29 import jdk.internal.misc.PreviewFeatures;
 30 import jdk.internal.misc.CDS;
 31 import jdk.internal.util.ClassFileDumper;
 32 import sun.invoke.util.VerifyAccess;
 33 
 34 import java.io.Serializable;
 35 import java.lang.classfile.ClassBuilder;
 36 import java.lang.classfile.ClassFile;
 37 import java.lang.classfile.CodeBuilder;
 38 import java.lang.classfile.MethodBuilder;
 39 import java.lang.classfile.Opcode;
 40 import java.lang.classfile.TypeKind;
 41 import java.lang.constant.ClassDesc;
 42 import java.lang.constant.MethodTypeDesc;
 43 import java.lang.reflect.ClassFileFormatVersion;
 44 import java.lang.reflect.Modifier;
 45 import java.util.LinkedHashSet;
 46 import java.util.List;
 47 import java.util.Set;
 48 import java.util.function.Consumer;
 49 
 50 import static java.lang.classfile.ClassFile.*;
 51 import java.lang.classfile.attribute.ExceptionsAttribute;
 52 import java.lang.classfile.constantpool.ClassEntry;
 53 import java.lang.classfile.constantpool.ConstantPoolBuilder;
 54 
 55 import static java.lang.constant.ConstantDescs.*;
 56 import static java.lang.invoke.MethodHandleNatives.Constants.NESTMATE_CLASS;
 57 import static java.lang.invoke.MethodHandleNatives.Constants.STRONG_LOADER_LINK;
 58 import jdk.internal.constant.ConstantUtils;
 59 import jdk.internal.constant.MethodTypeDescImpl;
 60 import jdk.internal.vm.annotation.Stable;
 61 import sun.invoke.util.Wrapper;
 62 
 63 /**

295     private Class<?> generateInnerClass() throws LambdaConversionException {
296         List<ClassDesc> interfaces;
297         ClassDesc interfaceDesc = classDesc(interfaceClass);
298         boolean accidentallySerializable = !isSerializable && Serializable.class.isAssignableFrom(interfaceClass);
299         if (altInterfaces.length == 0) {
300             interfaces = List.of(interfaceDesc);
301         } else {
302             // Assure no duplicate interfaces (ClassFormatError)
303             Set<ClassDesc> itfs = LinkedHashSet.newLinkedHashSet(altInterfaces.length + 1);
304             itfs.add(interfaceDesc);
305             for (Class<?> i : altInterfaces) {
306                 itfs.add(classDesc(i));
307                 accidentallySerializable |= !isSerializable && Serializable.class.isAssignableFrom(i);
308             }
309             interfaces = List.copyOf(itfs);
310         }
311         final boolean finalAccidentallySerializable = accidentallySerializable;
312         final byte[] classBytes = ClassFile.of().build(lambdaClassEntry, pool, new Consumer<ClassBuilder>() {
313             @Override
314             public void accept(ClassBuilder clb) {
315                 clb.withVersion(ClassFileFormatVersion.latest().major(), (PreviewFeatures.isEnabled() ? ClassFile.PREVIEW_MINOR_VERSION : 0))
316                    .withFlags(ACC_SUPER | ACC_FINAL | ACC_SYNTHETIC)
317                    .withInterfaceSymbols(interfaces);
318                 // All Classes in the BSM argument method types are loaded; no need for LoadableDescriptors
319 
320                 // Generate final fields to be filled in by constructor
321                 for (int i = 0; i < argDescs.length; i++) {
322                     clb.withField(argName(i), argDescs[i], ACC_PRIVATE | ACC_FINAL);
323                 }
324 
325                 generateConstructor(clb);
326 
327                 if (factoryType.parameterCount() == 0 && disableEagerInitialization) {
328                     generateClassInitializer(clb);
329                 }
330 
331                 // Forward the SAM method
332                 clb.withMethodBody(interfaceMethodName,
333                         methodDesc(interfaceMethodType),
334                         ACC_PUBLIC,
335                         forwardingMethod(interfaceMethodType));
336 
337                 // Forward the bridges
338                 if (altMethods != null) {
339                     for (MethodType mt : altMethods) {
< prev index next >