序列化后使用equals()

时间:2014-08-05 12:05:20

标签: java serialization equals

我有以下方法将文件(包含序列化对象)转换回对象:

public static <T, C extends Class<T>> T readSerializableObjectFromFile(final Path path, final C clazz) {
    Objects.requireNonNull(path, "path");
    Objects.requireNonNull(clazz, "clazz");
    try (ObjectInputStream objectInputStream = new ObjectInputStream(Files.newInputStream(path))) {
        return clazz.cast(objectInputStream.readObject());
    } catch (IOException ex) {
        throw new UncheckedIOException(ex);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(ex);
    }
}

假设我有一个Organization类型的对象,它有equalshashCode方法,写在文件中,当我调用以下内容时会发生什么?

Organization organization = 
    readSerializableObjectFromFile(myFile, Organization.class);

organization.hashCode()是否使用Object#hashCodeOrganization#hashCode实施?

当我在文件中存储List<Organization>然后通过

检索时,行为是否会发生变化
@SuppressWarnings("unchecked")
List<Organization> organizations =
    readSerializableObjectFromFile(myFile, List.class)

3 个答案:

答案 0 :(得分:2)

由于动态调度,每当您调用hashCode()或任何其他方法的方法时,调用的特定函数取决于对象的运行时类型(而不是声明的类型)对象)。 ObjectInputStream / ObjectOutputStream将保留对象的运行时类型(运行时类是在序列化上编写的,因此用于在反序列化时实例化对象)。

您的强制转换操作只是检查结果的类型是否正确(它不是反序列化数据属于该类型的原因),并且它不会导致数据被转换或截断(如果那是你担心或担心的话)。

对于List&lt; T&gt;,散列方法不依赖于特定类型参数。该类型被删除的事实(无论结构在内部表示的方式如何)都不会改变行为。

答案 1 :(得分:1)

  

假设我有一个Organization类型的对象,它有equalshashCode方法,写在文件中,当我调用以下内容时会发生什么?

当您调用readSerializableObjectFromFile方法时,将根据文件中的状态创建一个或多个新对象。你重写了hashcode和equals的事实并没有改变这个事实。

  

organization.hashCode()是否使用Object#hashCodeOrganization#hashCode实施?

使用的hashCode()版本的确定方式完全相同,无论是原始对象还是序列化/反序列化生成的副本。

  

当我在文件中存储List<Organization>然后将其检索

时,行为是否会发生变化

不,它没有。


这些问题有点奇怪......

...但也许您缺少的是当您使用Java对象流序列化和反序列化对象时,您得到的是原始对象的副本及其闭包。你没有得到相同的实例......

如果您的课程实施equalshashCode,那么&#34;基于身份的&#34;等于语义,然后复制的对象是不同的对象,因此不相等。但是,如果您的equalshashCode拥有&#34;基于价值的&#34;等式语义,复制的对象应该具有相同的&#34;值&#34; ...

答案 2 :(得分:0)

如何创建对象(直接使用构造函数,反序列化或通过克隆)并不重要。如果此对象的类定义了hashCode(或equals),则将使用该方法。