2

我需要弄清楚两个给定的接口实现是否相同。我天真的方法是通过以下方式粗略地测试他们的类的相等性: 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 对象构造有关。但我不明白它是如何发生的以及为什么会发生?

完整的示例代码。

4

0 回答 0