it is possible to serialize a lambda in Java 8でも、それはstrongly discouragedです。さらにserializing inner classes is discouraged。その理由は、lambdaが別のJREで正しくデシリアライズできない可能性があるからです。しかし、これは、がラムダを安全にシリアル化する方法であることを意味していませんか?ラムダを安全にシリアル化する方法は?
public class MyClass {
private String value;
private Predicate<String> validateValue;
public MyClass(String value, Predicate<String> validate) {
this.value = value;
this.validateValue = validate;
}
public void setValue(String value) {
if (!validateValue(value)) throw new IllegalArgumentException();
this.value = value;
}
public void setValidation(Predicate<String> validate) {
this.validateValue = validate;
}
}
私はこのようなクラスのインスタンスを宣言した場合、私はそれをシリアルべきではない:
MyClass obj = new MyClass("some value", (s) -> !s.isEmpty());
しかし、例えば、私はこのようなものにするためにクラスを定義
を言います
// Could even be a static nested class
public class IsNonEmpty implements Predicate<String>, Serializable {
@Override
public boolean test(String s) {
return !s.isEmpty();
}
}
:私はこのようなクラスのインスタンスを作ったものならば210
MyClass isThisSafeToSerialize = new MyClass("some string", new IsNonEmpty());
これでシリアル化するのが安全ですか?私の本能はそう言います、安全でなければなりません。なぜなら、java.util.function
のインターフェースは、他の任意のインターフェースとは異なった扱いをする必要がないからです。しかし、私はまだ注意しています。
インターフェイスはシリアライゼーションとは完全に無関係です。したがって、「述語」を実装すると他のインターフェイスを実装するのと同じ影響があります。しかし、ラムダが別のJREで正しく非直列化できないというあなたの前提は間違っています。[明確な永続表現](https://docs.oracle.com/javase/8/docs/api/?java/lang/invoke/SerializedLambda.html)があります。 – Holger
@Holger次に、[oracle docs](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#serialization)が、そうでないことを示唆しているのはなぜですか? – Justin
まあ、それには[シリアライズに関する内部クラス関連の問題](https://docs.oracle.com/javase/tutorial/java/jested/nested.html#serialization)への参照が含まれています。要するに、JRE固有の問題ではなく、コンパイラの依存関係を作成する可能性があります。確かに、テキストは少し誤解を招くことがあります。そして、 'this'を含む周囲の文脈の捕捉された値を誤って連載する危険に気をつけてください... – Holger