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
|