동일한 JVM에서 객체 목록을 직렬화 및 비 직렬화하는 데 문제가 있습니다. 알파벳 참조가 일치 최대 나던 어떤 시점에서, 객체 내 목록의 직렬화 afte 이제동일한 프로세스에서 java가 비 직렬화 및 직렬화
VMID instanceId = new VMID(); //used in readResolve to identify persitent instances
public Alphabet (int capacity, Class entryClass) {
this.map = new gnu.trove.TObjectIntHashMap (capacity);
this.entries = new ArrayList (capacity);
this.entryClass = entryClass;
// someone could try to deserialize us into this image (e.g., by RMI). Handle this.
deserializedEntries.put (instanceId, this);
}
public VMID getInstanceId() {
return instanceId;
} // for debugging
public void setInstanceId(VMID id) { this.instanceId = id; }
// Serialization
private static final long serialVersionUID = 1;
private static final int CURRENT_SERIAL_VERSION = 1;
private void writeObject (ObjectOutputStream out) throws IOException {
out.writeInt (CURRENT_SERIAL_VERSION);
out.writeInt (entries.size());
for (int i = 0; i < entries.size(); i++) {
out.writeObject (entries.get(i));
}
out.writeBoolean (growthStopped);
out.writeObject (entryClass);
out.writeObject(instanceId);
}
private void readObject (ObjectInputStream in) throws IOException, ClassNotFoundException {
int version = in.readInt();
int size = in.readInt();
entries = new ArrayList (size);
map = new gnu.trove.TObjectIntHashMap (size);
for (int i = 0; i < size; i++) {
Object o = in.readObject();
map.put (o, i);
entries. add (o);
}
growthStopped = in.readBoolean();
entryClass = (Class) in.readObject();
if (version >0){ // instanced id added in version 1S
instanceId = (VMID) in.readObject();
}
}
private transient static HashMap deserializedEntries = new HashMap();
/**
* This gets called after readObject; it lets the object decide whether
* to return itself or return a previously read in version.
* We use a hashMap of instanceIds to determine if we have already read
* in this object.
* @return
* @throws ObjectStreamException
*/
public Object readResolve() throws ObjectStreamException {
Object previous = deserializedEntries.get(instanceId);
if (previous != null){
//System.out.println(" ***Alphabet ReadResolve:Resolving to previous instance. instance id= " + instanceId);
return previous;
}
if (instanceId != null){
deserializedEntries.put(instanceId, this);
}
//System.out.println(" *** Alphabet ReadResolve: new instance. instance id= " + instanceId);
return this;
}
: 지금 내 개체는 다음과 같은 규칙이있는 Alphabet
객체에 동일한 기준을 유지, 정확합니다. 나는 다음과 같은 사용하여 검사를했다 :
for (Instance i: finalTrainingDocs){
if (!i.getTargetAlphabet().equals(finalTraining.getTargetAlphabet())){
System.out.println("not equals");
System.out.println(i.getTargetAlphabet().getInstanceId() + " " + finalTraining.getTargetAlphabet().getInstanceId());
}
finalTraining.add(i);
counter++;
System.out.println("counter " + counter);
}
을 그리고 다음과 같은 결과
counter 237
counter 238
counter 239
not equals
3ce62156867eb540:6b7f0de5:141e51fcd67:-7ffa 3ce62156867eb540:6b7f0de5:141e51fcd67:-7ffa
이제 VMID보고가 동일하기 때문에, 그것으로, 같은 객체 안을 돌아왔다 위의 논리? 도와 줘서 고맙다. 당신은 버전에 따라 InstanceID에 읽고있는
이러한 writeObject() 및 readObject() 메서드는 기본적으로 발생하는 것 이상의 값을 추가하는 것처럼 보이지 않습니다. – EJP
그 것처럼 보입니다. 그것의 오픈 소스 라이브러리에서 말렛 그래서 난 거기에 저자의 의도는 확실하지 않아요 – goh
나는 여기에 무슨 일이 일어나고 있는지 알아낼 수있는 충분한 코드가 있다고 생각하지 않습니다. 예를 들어, Alphabet.equals가 어떻게 구현되고, VMID의 코드는 어디에 있는가? –