Мне нужно выяснить, когда две указанные реализации интерфейса совпадают. Мой наивный подход состоял в том, чтобы проверить равенство их классов примерно:
first.getClass().equals(second.getClass())
. Это работает, пока мой код не встретил (де) сериализованные лямбда-выражения. Которые, кажется, изменяют свой экземпляр 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
Я озадачен этим. Почему лямбда меняет свой класс? И как еще можно распознать, когда две заданные реализации интерфейса одинаковы даже после сериализации?
Полагаю, это как-то связано с конструкцией лямбда-объекта времени выполнения . Но я не вижу, как и почему это происходит?
Полный пример кода.