下面的代码抛出
Exception in thread "main" java.lang.ClassCastException: test.Subclass2 cannot be cast to test.Subclass1
at test.LambdaTest.main(LambdaTest.java:17)
public class LambdaTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ToLongFunction<B> fn1 = serde((ToLongFunction<B> & Serializable) B::value);
ToLongFunction<C> fn2 = serde((ToLongFunction<C> & Serializable) C::value);
fn1.applyAsLong(new B());
fn2.applyAsLong(new C()); // Line 17 -- exception here!
}
private static <T extends Serializable> T serde(T t) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
new ObjectOutputStream(bos).writeObject(t);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos
.toByteArray()));
return (T) ois.readObject();
}
}
class A {
public long value() {
return 0;
}
}
class B extends A { }
class C extends A { }
原因好像是经过序列化和反序列化之后,fn1和fn2最终都是同一个类。这是 JDK/编译器错误还是我遗漏了有关 lambda 序列化和反序列化的内容?
最佳答案
看看 2016 年提出的这个 Open JDK 问题:
Deserialization of lambda causes ClassCastException
它非常符合您的场景:
- Two (distinct) classes,
B
andC
, both of which extend the same base class,A
, which has a method,String f()
.- Create a
Supplier
reference to methodf()
for an object of typeB
; call thisbf
[new B()::f
].- Create a
Supplier
reference to methodf()
for an object of typeC
; cal thiscf
[new C()::f
].- Serialize
cf
(ObjectOutputStream#writeObject
)- When the serialized
cf
is deserialized (ObjectInputStream#readObject
), aClassCastException
is thrown saying that classC
cannot be cast to classB
关于这个问题有一个有趣的讨论,但 Dan Smith 的最后评论似乎一语中的:
Important observation for this particular test case: the "qualifying type" (i.e., the class named by the bytecode) of a method reference should be the same as the qualifying type of an invocation: the type of the receiver. javac is wrong to be using the type of the declaring class. See JDK-8059632.
Fix that bug, and I think the issue with different captured types goes away.
关于java - lambda的序列化和反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48840989/