gpt4 book ai didi

java - 为其他对象实现等价于 String.intern()

转载 作者:行者123 更新时间:2023-11-29 05:23:25 26 4
gpt4 key购买 nike

我正在尝试实现与 String.intern() 等效的功能,但用于其他对象。我的目标如下:我有一个对象 A,我将对其进行序列化然后反序列化。如果某处有另一个对 A 的引用,我希望反序列化的结果是相同的引用。

这是我所期望的一个示例。

MyObject A = new MyObject();
A.data1 = 1;
A.data2 = 2;
byte[] serialized = serialize(A);
A.data1 = 3;
MyObject B = deserialize(serialized); // B!=A and B.data1=1, B.data2=2
MyObject C = B.intern(); // Here we should have C == A. Consequently C.data1=3 AND C.data2=2

这是我的实现 atm。 (MyObject 类扩展了 InternableObject)

public abstract class InternableObject {

private static final AtomicLong maxObjectId = new AtomicLong();
private static final Map<Long, InternableObject> dataMap = new ConcurrentHashMap<>();
private final long objectId;

public InternableObject() {
this.objectId = maxObjectId.incrementAndGet();

dataMap.put(this.objectId, this);
}

@Override
protected void finalize() throws Throwable {
super.finalize();
dataMap.remove(this.objectId);
}

public final InternableObject intern() {
return intern(this);
}

public static InternableObject intern(InternableObject o) {
InternableObject r = dataMap.get(o.objectId);

if (r == null) {
throw new IllegalStateException();
} else {
return r;
}
}
}

我的单元测试(失败):

    private static class MyData extends InternableObject implements Serializable {

public int data;

public MyData(int data) {
this.data = data;
}
}

@Test
public void testIntern() throws Exception {
MyData data1 = new MyData(7);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(data1);
oos.flush();
baos.flush();
oos.close();
baos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
MyData data2 = (MyData) ois.readObject();

Assert.assertTrue(data1 == data2.intern()); // Fails here
}

失败是因为在反序列化的时候,调用了InternableObject的构造函数,所以objectId会是2(即使序列化后的数据是“1”)

关于如何解决这个特定问题或处理高级问题的另一种方法有什么想法吗?

谢谢大家

最佳答案

不要使用构造函数来创建实例。使用工厂方法首先检查实例是否已存在,只有在不存在匹配实例时才创建实例。

要使序列化协作,您的类需要使用 readResolve()/writeReplace()。 http://docs.oracle.com/javase/7/docs/platform/serialization/spec/serial-arch.html#4539

您实现构造函数的方式会在构造过程中泄漏引用,这会导致非常难以确定的问题。此外,您的实例映射不受任何锁保护,因此它不是线程保存。

关于java - 为其他对象实现等价于 String.intern(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23744201/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com