我需要弄清楚两个给定的接口实现是否相同。我天真的方法是通过以下方式粗略地测试他们的类的相等性:
first.getClass().equals(second.getClass()). 它一直有效,直到我的代码遇到(反)序列化的 lambda 表达式。这似乎Class在反序列化期间改变了它们的实例。以下示例说明了这种情况:
public interface SerializableSupplier<T> extends Serializable{
T get();
}
private static final SerializableSupplier<Integer> FINAL_SUPPLIER = () -> 8;
public static void main(String args[]) throws IOException, ClassNotFoundException {
ByteArrayOutputStream outStr = new ByteArrayOutputStream();
ObjectOutputStream oss = new ObjectOutputStream(outStr);
oss.writeObject(FINAL_SUPPLIER);
oss.flush();
oss.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(outStr.toByteArray()));
SerializableSupplier<Integer> supplierDeserialized = (SerializableSupplier<Integer>) ois.readObject();
System.out.println(FINAL_SUPPLIER.getClass());
System.out.println(supplierDeserialized.getClass());
System.out.println(FINAL_SUPPLIER.getClass().equals(supplierDeserialized.getClass()));
}
哪个打印:
class cz.plastique.examples.LambdaChangingClass$$Lambda$1/295530567
class cz.plastique.examples.LambdaChangingClass$$Lambda$4/1854731462
false
使用匿名实现时行为不同:
private static final SerializableSupplier<Integer> ANONYMOUS_FINAL_SUPPLIER =
new SerializableSupplier<Integer>() {
@Override
public Integer get() {
return 8;
}
};
哪个打印:
class cz.plastique.examples.LambdaChangingClass$1
class cz.plastique.examples.LambdaChangingClass$1
true
我对此感到困惑。为什么 lambda 会改变它的类?即使在序列化之后,只要两个给定的接口实现相同,a 还能如何识别?
我想这与运行时 lambda 对象构造有关。但我不明白它是如何发生的以及为什么会发生?