< prev index next >

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

Print this page

      1 /*
      2  * Copyright (c) 2012, 2019, 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
     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     @SuppressWarnings("serial") // Not statically typed as Serializable
     80     private final Object[] capturedArgs;
     81
     82     /**
     83      * Create a {@code SerializedLambda} from the low-level information present
     84      * at the lambda factory site.
     85      *
     86      * @param capturingClass The class in which the lambda expression appears
     87      * @param functionalInterfaceClass Name, in slash-delimited form, of static
     88      *                                 type of the returned lambda object
     89      * @param functionalInterfaceMethodName Name of the functional interface
     90      *                                      method for the present at the
     91      *                                      lambda factory site
     92      * @param functionalInterfaceMethodSignature Signature of the functional
     93      *                                           interface method present at
     94      *                                           the lambda factory site
     95      * @param implMethodKind Method handle kind for the implementation method
     96      * @param implClass Name, in slash-delimited form, for the class holding
     97      *                  the implementation method
     98      * @param implMethodName Name of the implementation method
    210         return instantiatedMethodType;
    211     }
    212
    213     /**
    214      * Get the count of dynamic arguments to the lambda capture site.
    215      * @return the count of dynamic arguments to the lambda capture site
    216      */
    217     public int getCapturedArgCount() {
    218         return capturedArgs.length;
    219     }
    220
    221     /**
    222      * Get a dynamic argument to the lambda capture site.
    223      * @param i the argument to capture
    224      * @return a dynamic argument to the lambda capture site
    225      */
    226     public Object getCapturedArg(int i) {
    227         return capturedArgs[i];
    228     }
    229

    230     @java.io.Serial
    231     private Object readResolve() throws ObjectStreamException {
    232         try {
    233             Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
    234                 @Override
    235                 public Method run() throws Exception {
    236                     Method m = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
    237                     m.setAccessible(true);
    238                     return m;
    239                 }
    240             });
    241
    242             return deserialize.invoke(null, this);
    243         } catch (ReflectiveOperationException roe) {
    244             ObjectStreamException ose = new InvalidObjectException("ReflectiveOperationException during deserialization");
    245             ose.initCause(roe);
    246             throw ose;
    247         } catch (PrivilegedActionException e) {
    248             Exception cause = e.getException();
    249             if (cause instanceof RuntimeException)
      1 /*
      2  * Copyright (c) 2012, 2020, 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
     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     /**
     71      * The capturing class.
     72      */
     73     private final Class<?> capturingClass;
     74     /**
     75      * The functional interface class.
     76      */
     77     private final String functionalInterfaceClass;
     78     /**
     79      * The functional interface method name.
     80      */
     81     private final String functionalInterfaceMethodName;
     82     /**
     83      * The functional interface method signature.
     84      */
     85     private final String functionalInterfaceMethodSignature;
     86     /**
     87      * The implementation class.
     88      */
     89     private final String implClass;
     90     /**
     91      * The implementation method name.
     92      */
     93     private final String implMethodName;
     94     /**
     95      * The implementation method signature.
     96      */
     97     private final String implMethodSignature;
     98     /**
     99      * The implementation method kind.
    100      */
    101     private final int implMethodKind;
    102     /**
    103      * The instantiated method type.
    104      */
    105     private final String instantiatedMethodType;
    106     /**
    107      * The captured arguments.
    108      */
    109     @SuppressWarnings("serial") // Not statically typed as Serializable
    110     private final Object[] capturedArgs;
    111
    112     /**
    113      * Create a {@code SerializedLambda} from the low-level information present
    114      * at the lambda factory site.
    115      *
    116      * @param capturingClass The class in which the lambda expression appears
    117      * @param functionalInterfaceClass Name, in slash-delimited form, of static
    118      *                                 type of the returned lambda object
    119      * @param functionalInterfaceMethodName Name of the functional interface
    120      *                                      method for the present at the
    121      *                                      lambda factory site
    122      * @param functionalInterfaceMethodSignature Signature of the functional
    123      *                                           interface method present at
    124      *                                           the lambda factory site
    125      * @param implMethodKind Method handle kind for the implementation method
    126      * @param implClass Name, in slash-delimited form, for the class holding
    127      *                  the implementation method
    128      * @param implMethodName Name of the implementation method
    240         return instantiatedMethodType;
    241     }
    242
    243     /**
    244      * Get the count of dynamic arguments to the lambda capture site.
    245      * @return the count of dynamic arguments to the lambda capture site
    246      */
    247     public int getCapturedArgCount() {
    248         return capturedArgs.length;
    249     }
    250
    251     /**
    252      * Get a dynamic argument to the lambda capture site.
    253      * @param i the argument to capture
    254      * @return a dynamic argument to the lambda capture site
    255      */
    256     public Object getCapturedArg(int i) {
    257         return capturedArgs[i];
    258     }
    259
    260     /**
    261      * Resolve a {@code SerializedLambda} to an object.
    262      * @return a SerializedLambda
    263      * @throws ObjectStreamException if the object is not valid
    264      */
    265     @java.io.Serial
    266     private Object readResolve() throws ObjectStreamException {
    267         try {
    268             Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
    269                 @Override
    270                 public Method run() throws Exception {
    271                     Method m = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
    272                     m.setAccessible(true);
    273                     return m;
    274                 }
    275             });
    276
    277             return deserialize.invoke(null, this);
    278         } catch (ReflectiveOperationException roe) {
    279             ObjectStreamException ose = new InvalidObjectException("ReflectiveOperationException during deserialization");
    280             ose.initCause(roe);
    281             throw ose;
    282         } catch (PrivilegedActionException e) {
    283             Exception cause = e.getException();
    284             if (cause instanceof RuntimeException)

< prev index next >