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

Print this page
rev 7978 : force early generated class initialization from metafactory and join subsequent doPrivelegedActions


 155     /**
 156      * Build the CallSite. Generate a class file which implements the functional
 157      * interface, define the class, if there are no parameters create an instance
 158      * of the class which the CallSite will return, otherwise, generate handles
 159      * which will call the class' constructor.
 160      *
 161      * @return a CallSite, which, when invoked, will return an instance of the
 162      * functional interface
 163      * @throws ReflectiveOperationException
 164      * @throws LambdaConversionException If properly formed functional interface
 165      * is not found
 166      */
 167     @Override
 168     CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException {
 169         final Class<?> innerClass = spinInnerClass();
 170         if (invokedType.parameterCount() == 0) {
 171             final Constructor[] ctrs = AccessController.doPrivileged(
 172                     new PrivilegedAction<Constructor[]>() {
 173                 @Override
 174                 public Constructor[] run() {
 175                     return innerClass.getDeclaredConstructors();






 176                 }
 177             });
 178             if (ctrs.length != 1) {
 179                 throw new ReflectiveOperationException("Expected one lambda constructor for "
 180                         + innerClass.getCanonicalName() + ", got " + ctrs.length);
 181             }
 182             // The lambda implementing inner class constructor is private, set
 183             // it accessible (by us) before creating the constant sole instance
 184             AccessController.doPrivileged(new PrivilegedAction<Void>() {
 185                 @Override
 186                 public Void run() {
 187                     ctrs[0].setAccessible(true);
 188                     return null;
 189                 }
 190             });
 191             Object inst = ctrs[0].newInstance();
 192             return new ConstantCallSite(MethodHandles.constant(samBase, inst));
 193         } else {



 194             return new ConstantCallSite(
 195                     MethodHandles.Lookup.IMPL_LOOKUP
 196                          .findConstructor(innerClass, constructorType)
 197                          .asType(constructorType.changeReturnType(samBase)));
 198         }
 199     }
 200 
 201     /**
 202      * Generate a class file which implements the functional
 203      * interface, define and return the class.
 204      *
 205      * @implNote The class that is generated does not include signature
 206      * information for exceptions that may be present on the SAM method.
 207      * This is to reduce classfile size, and is harmless as checked exceptions
 208      * are erased anyway, no one will ever compile against this classfile,
 209      * and we make no guarantees about the reflective properties of lambda
 210      * objects.
 211      *
 212      * @return a Class which implements the functional interface
 213      * @throws LambdaConversionException If properly formed functional interface




 155     /**
 156      * Build the CallSite. Generate a class file which implements the functional
 157      * interface, define the class, if there are no parameters create an instance
 158      * of the class which the CallSite will return, otherwise, generate handles
 159      * which will call the class' constructor.
 160      *
 161      * @return a CallSite, which, when invoked, will return an instance of the
 162      * functional interface
 163      * @throws ReflectiveOperationException
 164      * @throws LambdaConversionException If properly formed functional interface
 165      * is not found
 166      */
 167     @Override
 168     CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException {
 169         final Class<?> innerClass = spinInnerClass();
 170         if (invokedType.parameterCount() == 0) {
 171             final Constructor[] ctrs = AccessController.doPrivileged(
 172                     new PrivilegedAction<Constructor[]>() {
 173                 @Override
 174                 public Constructor[] run() {
 175                     Constructor<?>[] ctrs = innerClass.getDeclaredConstructors();
 176                     if (ctrs.length == 1) {
 177                         // The lambda implementing inner class constructor is private, set
 178                         // it accessible (by us) before creating the constant sole instance
 179                         ctrs[0].setAccessible(true);
 180                     }
 181                     return ctrs;
 182                 }
 183             });
 184             if (ctrs.length != 1) {
 185                 throw new ReflectiveOperationException("Expected one lambda constructor for "
 186                         + innerClass.getCanonicalName() + ", got " + ctrs.length);
 187             }









 188             Object inst = ctrs[0].newInstance();
 189             return new ConstantCallSite(MethodHandles.constant(samBase, inst));
 190         } else {
 191             if (UNSAFE.shouldBeInitialized(innerClass)) {
 192                 UNSAFE.ensureClassInitialized(innerClass);
 193             }
 194             return new ConstantCallSite(
 195                     MethodHandles.Lookup.IMPL_LOOKUP
 196                          .findConstructor(innerClass, constructorType)
 197                          .asType(constructorType.changeReturnType(samBase)));
 198         }
 199     }
 200 
 201     /**
 202      * Generate a class file which implements the functional
 203      * interface, define and return the class.
 204      *
 205      * @implNote The class that is generated does not include signature
 206      * information for exceptions that may be present on the SAM method.
 207      * This is to reduce classfile size, and is harmless as checked exceptions
 208      * are erased anyway, no one will ever compile against this classfile,
 209      * and we make no guarantees about the reflective properties of lambda
 210      * objects.
 211      *
 212      * @return a Class which implements the functional interface
 213      * @throws LambdaConversionException If properly formed functional interface