Possibility to explicit remove Serialization support for a lambda

前端 未结 1 1064
温柔的废话
温柔的废话 2020-12-01 02:37

As already known it’s easy to add Serialization support to a lambda expression when the target interface does not already inherit Serializable, just li

1条回答
  •  失恋的感觉
    2020-12-01 03:38

    How to handle serializability was one of the biggest challenges for the EG; suffice it to say that there were no great solutions, only tradeoffs between various downsides. Some parties insisted that all lambdas be automatically serializable (!); others insisted that lambdas never be serializable (which seemed an attractive idea at times, but sadly would badly violate user expectations.)

    You note:

    Well, another solution is to never use lambda expressions/method references in security relevant code,

    In fact, the serialization spec now says exactly that.

    But, there is a fairly easy trick to do what you want here. Suppose you have some library that wants serializable instances:

    public interface SomeLibType extends Runnable, Serializable { }
    

    with methods that expect this type:

    public void gimmeLambda(SomeLibType r)
    

    and you want to pass lambdas into it, but not have them be serializable (and take the consequences of that.) So, write yourself this helper method:

    public static SomeLibType launder(Runnable r) {
        return new SomeLibType() {
            public void run() { r.run(); }
        }
    }
    

    Now you can call the library method:

    gimmeLambda(launder(() -> myPrivateMethod()));
    

    The compiler will convert your lambda into a non-serializable Runnable, and the laundering wrapper will wrap it with an instance that satisifies the type system. When you try to serialize it, that will fail since r is not serializable. More importantly, you can't forge access to the private method, because the $deserializeLambda$ support that's needed in the capturing class won't even be there.

    0 讨论(0)
提交回复
热议问题