String.intern()과 동일한 기능을 구현하려고하지만 다른 객체는 구현하려고합니다. 내 목표는 다음과 같습니다. 개체 A를 직렬화 한 다음 비 직렬화 할 것입니다. 어딘가에 A라는 또 다른 참조가있는 경우, deserialization의 결과가 같은 참조가되기를 원합니다.다른 객체에 대해 String.intern()과 동일한 기능 구현
내가 예상하는 것의 한 예입니다.
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입니다. (실패)
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;
}
}
}
내 단위 테스트합니다 (MyObject
클래스 InternableObject
확장)
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"이 포함되어 있어도)
이 특정 문제를 해결하는 방법이나 상위 수준의 문제를 처리하는 다른 방법에 대한 아이디어가 있습니까?
고마워요
문자열은 '불변'이므로이를 이해하는 것이 바람직합니다. 왜 당신은 임의의 객체에 대해이 기능을 원할 것입니까? –
영감을 얻기 위해 '통화'의 출처를 살펴 보는 것이 좋습니다. – chrylis