48 * serialization to proceed.
49 *
50 * <p>{@code SerializedLambda} has a {@code readResolve} method that looks for
51 * a (possibly private) static method called
52 * {@code $deserializeLambda$(SerializedLambda)} in the capturing class, invokes
53 * that with itself as the first argument, and returns the result. Lambda classes
54 * implementing {@code $deserializeLambda$} are responsible for validating
55 * that the properties of the {@code SerializedLambda} are consistent with a
56 * lambda actually captured by that class.
57 *
58 * <p>The identity of a function object produced by deserializing the serialized
59 * form is unpredictable, and therefore identity-sensitive operations (such as
60 * reference equality, object locking, and {@code System.identityHashCode()} may
61 * produce different results in different implementations, or even upon
62 * different deserializations in the same implementation.
63 *
64 * @see LambdaMetafactory
65 * @since 1.8
66 */
67 public final class SerializedLambda implements Serializable {
68 private static final long serialVersionUID = 8025925345765570181L;
69 private final Class<?> capturingClass;
70 private final String functionalInterfaceClass;
71 private final String functionalInterfaceMethodName;
72 private final String functionalInterfaceMethodSignature;
73 private final String implClass;
74 private final String implMethodName;
75 private final String implMethodSignature;
76 private final int implMethodKind;
77 private final String instantiatedMethodType;
78 private final Object[] capturedArgs;
79
80 /**
81 * Create a {@code SerializedLambda} from the low-level information present
82 * at the lambda factory site.
83 *
84 * @param capturingClass The class in which the lambda expression appears
85 * @param functionalInterfaceClass Name, in slash-delimited form, of static
86 * type of the returned lambda object
87 * @param functionalInterfaceMethodName Name of the functional interface
208 return instantiatedMethodType;
209 }
210
211 /**
212 * Get the count of dynamic arguments to the lambda capture site.
213 * @return the count of dynamic arguments to the lambda capture site
214 */
215 public int getCapturedArgCount() {
216 return capturedArgs.length;
217 }
218
219 /**
220 * Get a dynamic argument to the lambda capture site.
221 * @param i the argument to capture
222 * @return a dynamic argument to the lambda capture site
223 */
224 public Object getCapturedArg(int i) {
225 return capturedArgs[i];
226 }
227
228 private Object readResolve() throws ObjectStreamException {
229 try {
230 Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
231 @Override
232 public Method run() throws Exception {
233 Method m = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
234 m.setAccessible(true);
235 return m;
236 }
237 });
238
239 return deserialize.invoke(null, this);
240 } catch (ReflectiveOperationException roe) {
241 ObjectStreamException ose = new InvalidObjectException("ReflectiveOperationException during deserialization");
242 ose.initCause(roe);
243 throw ose;
244 } catch (PrivilegedActionException e) {
245 Exception cause = e.getException();
246 if (cause instanceof RuntimeException)
247 throw (RuntimeException) cause;
|
48 * serialization to proceed.
49 *
50 * <p>{@code SerializedLambda} has a {@code readResolve} method that looks for
51 * a (possibly private) static method called
52 * {@code $deserializeLambda$(SerializedLambda)} in the capturing class, invokes
53 * that with itself as the first argument, and returns the result. Lambda classes
54 * implementing {@code $deserializeLambda$} are responsible for validating
55 * that the properties of the {@code SerializedLambda} are consistent with a
56 * lambda actually captured by that class.
57 *
58 * <p>The identity of a function object produced by deserializing the serialized
59 * form is unpredictable, and therefore identity-sensitive operations (such as
60 * reference equality, object locking, and {@code System.identityHashCode()} may
61 * produce different results in different implementations, or even upon
62 * different deserializations in the same implementation.
63 *
64 * @see LambdaMetafactory
65 * @since 1.8
66 */
67 public final class SerializedLambda implements Serializable {
68 @java.io.Serial
69 private static final long serialVersionUID = 8025925345765570181L;
70 private final Class<?> capturingClass;
71 private final String functionalInterfaceClass;
72 private final String functionalInterfaceMethodName;
73 private final String functionalInterfaceMethodSignature;
74 private final String implClass;
75 private final String implMethodName;
76 private final String implMethodSignature;
77 private final int implMethodKind;
78 private final String instantiatedMethodType;
79 private final Object[] capturedArgs;
80
81 /**
82 * Create a {@code SerializedLambda} from the low-level information present
83 * at the lambda factory site.
84 *
85 * @param capturingClass The class in which the lambda expression appears
86 * @param functionalInterfaceClass Name, in slash-delimited form, of static
87 * type of the returned lambda object
88 * @param functionalInterfaceMethodName Name of the functional interface
209 return instantiatedMethodType;
210 }
211
212 /**
213 * Get the count of dynamic arguments to the lambda capture site.
214 * @return the count of dynamic arguments to the lambda capture site
215 */
216 public int getCapturedArgCount() {
217 return capturedArgs.length;
218 }
219
220 /**
221 * Get a dynamic argument to the lambda capture site.
222 * @param i the argument to capture
223 * @return a dynamic argument to the lambda capture site
224 */
225 public Object getCapturedArg(int i) {
226 return capturedArgs[i];
227 }
228
229 @java.io.Serial
230 private Object readResolve() throws ObjectStreamException {
231 try {
232 Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
233 @Override
234 public Method run() throws Exception {
235 Method m = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
236 m.setAccessible(true);
237 return m;
238 }
239 });
240
241 return deserialize.invoke(null, this);
242 } catch (ReflectiveOperationException roe) {
243 ObjectStreamException ose = new InvalidObjectException("ReflectiveOperationException during deserialization");
244 ose.initCause(roe);
245 throw ose;
246 } catch (PrivilegedActionException e) {
247 Exception cause = e.getException();
248 if (cause instanceof RuntimeException)
249 throw (RuntimeException) cause;
|