< prev index next >

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

Print this page




  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;


< prev index next >