我正在使用Swing编写Java应用程序。我正在尝试实现保存和加载模拟状态的功能,以便我正在运行的模拟。整个模拟作为对象保持不变,与Swing断开连接。我正在尝试使用以下代码序列化我的Simulation类:
public void saveSimulationState(String simulationFile) {
try {
Serializable object = this.sm;
ObjectOutputStream objstream = new ObjectOutputStream(new FileOutputStream(simulationFile));
objstream.writeObject(object);
objstream.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
但我收到以下错误(很大)。
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.io.ObjectStreamClass.processQueue(ObjectStreamClass.java:2234)
at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:266)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1106)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
有人能告诉我是什么导致了这个例外吗?
答案 0 :(得分:12)
陈的有趣帖子:
When debugging a stack overflow, you want to focus on the repeating recursive part
在你的情况下:
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
如果您正在寻找缺陷跟踪数据库,试图查看这是否是一个已知问题,那么搜索堆栈顶部函数不太可能发现任何有趣的内容。这是因为堆栈溢出往往发生在递归中的随机点;即使堆栈溢出相同,每个堆栈溢出看起来也与其他堆栈溢出不同。
一旦你经历了最初的混乱,堆栈的痕迹就会一次又一次地由一个相同的x函数组成一个漂亮的重复模式。
识别重复模式的开始并不重要,因为每个崩溃的起点都不同,就像超过你的演唱范围的精确音符从崩溃到崩溃一样。一旦你确定了重复部分,从中选择一个有点不寻常的函数并在your defect database中搜索它。
For example,默认ArrayList
序列化。
此处,您的GrahPanel
引用的Simulation
引用Graph
,传感器和边缘可能很长ArrayList
...
Java序列化会记录写入流的每个对象。如果第二次遇到同一个对象,则只将对它的引用写入流,而不是该对象的第二个副本;所以循环引用不是问题所在。
但是对于某些类型的结构,序列化容易受到堆栈溢出的影响;例如,没有特殊writeObject()方法的长链表将通过递归写入每个链接来序列化。如果您有100,000个链接,那么您将尝试使用100,000个堆栈帧,并且很可能因StackOverflowError 而失败。
可以为这样的列表类定义一个writeObject()方法,当第一个链接被序列化时,只需遍历列表并迭代地序列化每个链接;这将阻止使用默认的递归机制。
答案 1 :(得分:2)
您应该考虑重新实现Simulation类的writeObject
/ readObject
方法,以便仅序列化相关数据(而不是默认情况下不是整个包含的对象结构)或标记瞬态不是序列化对象。
如果需要,您还可以使用Externalizable
界面。
顺便说一下,您可能希望先阅读此interesting article。
答案 2 :(得分:1)
你有一些深度嵌套的ArrayLists。
我想也许它只是先深入,这意味着它将用于底部传感器,这太深了。
也许您可以创建一个自定义结构,传感器从底部传感器开始?
或者您可能必须提供自己的序列化来处理它? http://java.sun.com/developer/technicalArticles/Programming/serialization/
答案 3 :(得分:0)
您应该为要存储的对象创建容器类。我不会用这里面的所有逻辑存储完整的这个对象。
按字段存储第一个字段以查找要以那种方式存储它的大元素。 然后在方法中放置一个断点并查看字段元素。元素是否包含相互链接的链接?
答案 4 :(得分:0)
完成所有操作后,只需使用XStream,如果您只想保存到文件中。
答案 5 :(得分:0)
使用更大的堆栈运行java
答案 6 :(得分:0)
此代码应作为模型,因为它解决了序列化时stackoverflow的问题。它使用内存代替递归。虽然不适合作为序列化程序通用,但它对所测试的类进行序列化和反序列化。
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
import android.util.*;
public class SequentialObjectInputStream extends DataInputStream implements ObjectInput
{
interface FieldPutAction
{
void put(Object obj, Field field) throws IllegalAccessException, IOException;
}
interface ArrayPutAction
{
void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException;
}
public HashMap<Class, FieldPutAction> Primatives;
public HashMap<Class, ArrayPutAction> ArrayPrimatives;
public SequentialObjectInputStream(InputStream stream)
{
super(stream);
Primatives = new HashMap<Class, FieldPutAction>();
try
{
Primatives.put(boolean.class,
new FieldPutAction()
{
public void put(Object obj, Field field) throws IllegalAccessException, IOException
{
boolean x = readBoolean();
field.setBoolean(obj, x);
}
});
Primatives.put(byte.class,
new FieldPutAction()
{
public void put(Object obj, Field field) throws IllegalAccessException, IOException
{
byte x = readByte();
field.setByte(obj, x);
}
});
Primatives.put(short.class,
new FieldPutAction()
{
public void put(Object obj, Field field) throws IllegalAccessException, IOException
{
short x = readShort();
field.setShort(obj, x);
}
});
Primatives.put(int.class,
new FieldPutAction()
{
public void put(Object obj, Field field) throws IllegalAccessException, IOException
{
int x = readInt();
field.setInt(obj, x);
}
});
Primatives.put(long.class,
new FieldPutAction()
{
public void put(Object obj, Field field) throws IllegalAccessException, IOException
{
long x = readLong();
field.setLong(obj, x);
}
});
Primatives.put(char.class,
new FieldPutAction()
{
public void put(Object obj, Field field) throws IllegalAccessException, IOException
{
char x = readChar();
field.setChar(obj, x);
}
});
Primatives.put(float.class,
new FieldPutAction()
{
public void put(Object obj, Field field) throws IllegalAccessException, IOException
{
float x = readFloat();
field.setFloat(obj, x);
}
});
Primatives.put(double.class,
new FieldPutAction()
{
public void put(Object obj, Field field) throws IllegalAccessException, IOException
{
double x = readDouble();
field.setDouble(obj, x);
}
});
Primatives.put(String.class,
new FieldPutAction()
{
public void put(Object obj, Field field) throws IllegalAccessException, IOException
{
String x = readUTF();
field.set(obj, x);
}
});
} catch(Exception e)
{
Log.e("SOb", Log.getStackTraceString(e));
}
ArrayPrimatives = new HashMap<Class, ArrayPutAction>();
try
{
ArrayPrimatives.put(boolean.class,
new ArrayPutAction()
{
public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
boolean x = readBoolean();
Array.setBoolean(obj, index, x);
}
});
ArrayPrimatives.put(byte.class,
new ArrayPutAction()
{
public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
byte x = readByte();
Array.setByte(obj, index, x);
}
});
ArrayPrimatives.put(short.class,
new ArrayPutAction()
{
public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
short x = readShort();
Array.setShort(obj, index, x);
}
});
ArrayPrimatives.put(int.class,
new ArrayPutAction()
{
public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
int x = readInt();
Array.setInt(obj, index, x);
}
});
ArrayPrimatives.put(long.class,
new ArrayPutAction()
{
public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
long x = readLong();
Array.setLong(obj, index, x);
}
});
ArrayPrimatives.put(char.class,
new ArrayPutAction()
{
public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
char x = readChar();
Array.setChar(obj, index, x);
}
});
ArrayPrimatives.put(float.class,
new ArrayPutAction()
{
public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
float x = readFloat();
Array.setFloat(obj, index, x);
}
});
ArrayPrimatives.put(double.class,
new ArrayPutAction()
{
public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
double x = readDouble();
Array.setDouble(obj, index, x);
}
});
ArrayPrimatives.put(String.class,
new ArrayPutAction()
{
public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
String x = readUTF();
Array.set(obj, index, x);
}
});
} catch(Exception e)
{
Log.e("SOb", Log.getStackTraceString(e));
}
}
@Override
public Object readObject() throws ClassNotFoundException, IOException
{
long Total = readLong();
Log.i("SOb", "readObject : " + Long.toString(Total) + " objects in graph");
HashMap<Long, Object> References = new HashMap<Long, Object>();
long currentId = 1;
HashMap<Object, HashMap<Field, Long>> refCache =
new HashMap<Object, HashMap<Field, Long>>();
final HashMap<Object, HashMap<Integer, Long>> arefCache =
new HashMap<Object, HashMap<Integer,Long>>();
for (int I=0; I < Total; I++)
{
String Name = readUTF();
Class C = Class.forName(Name);
Log.i("SOb", "Object of "+C.getCanonicalName() +" on graph");
int adim = 0;
Object O = null;
if (C.isArray())
{
Class ComponentType = C.getComponentType();
int Size = readInt();
Log.i("SOb", "array of "+ComponentType.getCanonicalName() + ", " + Long.toString(Size) + " elements");
O = Array.newInstance(ComponentType, Size);
References.put(currentId, O);
currentId++;
ArrayPutAction action = null;
if (ArrayPrimatives.keySet().contains(ComponentType))
{
action = ArrayPrimatives.get(ComponentType);
} else
{
arefCache.put(O, new HashMap<Integer, Long>());
action = new ArrayPutAction()
{
public void put(Object O, int Index) throws ArrayIndexOutOfBoundsException , IOException
{
long Ref = readLong();
arefCache.get(O).put(Index, Ref);
}
};
}
for (int index=0; index< Size; index++)
{
action.put(O,index);
}
} else
{
try
{
O =
C.getConstructor(new Class[0]).newInstance(new Object[0]);
} catch(InstantiationException e)
{
Log.e("SOb", Log.getStackTraceString(e));
} catch(NoSuchMethodException e)
{
Log.e("SOb", Log.getStackTraceString(e));
} catch(IllegalAccessException e)
{
Log.e("SOb", Log.getStackTraceString(e));
} catch(InvocationTargetException e)
{
Log.e("SOb", Log.getStackTraceString(e));
}
References.put(currentId, O);
currentId++;
refCache.put(O, new HashMap<Field, Long>());
for (Field F : C.getFields())
{
if (F.isAccessible())
{
Class T = F.getType();
if (Primatives.containsKey(T))
{
try
{
Primatives.get(T).put(O, F);
} catch (IllegalAccessException e)
{
}
} else
{
refCache.get(O).put(F, readLong());
}
}
}
}
}
for (long I=0; I < Total; I++)
{
Object O = References.get(I+1);
Class C = O.getClass();
//Log.i("SOb", "get reference "+Long.toString(I)+" "+C.getCanonicalName());
if (C.isArray())
{
HashMap<Integer,Long> aref_table = arefCache.get(O);
if (ArrayPrimatives.containsKey(C.getComponentType()) == false)
{
int len = Array.getLength(O);
for (int index=0; index<len; index++)
{
long r = aref_table.get(index);
Object ref = r == 0 ? null : References.get(r);
Array.set(O, index, ref);
}
}
} else
{
HashMap<Field, Long> ref_table = refCache.get(O);
for (Field F : C.getFields())
{
if (F.isAccessible())
{
Class T = F.getType();
if (Primatives.containsKey(T) == false)
{
try
{
long r = ref_table.get(F);
Object ref = r == 0 ? null : References.get(r);
F.set(O, ref);
} catch (IllegalAccessException e)
{
Log.e("SOb", Log.getStackTraceString(e));
}
}
}
}
}
}
return References.get((Long) (long) 1);
}
}
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
import android.util.*;
public class SequentialObjectOutputStream extends DataOutputStream
implements ObjectOutput
{
interface FieldGetAction
{
void get(Object obj, Field field) throws IllegalAccessException, IOException;
}
interface ArrayGetAction
{
void get(Object array, int Index) throws ArrayIndexOutOfBoundsException, IOException;
}
public HashMap<Class, FieldGetAction> Primatives;
public HashMap<Class, ArrayGetAction> ArrayPrimatives;
public SequentialObjectOutputStream(OutputStream stream)
{
super(stream);
Primatives = new HashMap<Class, FieldGetAction>();
try
{
Primatives.put(boolean.class,
new FieldGetAction()
{
public void get(Object obj, Field field) throws IllegalAccessException, IOException
{
boolean x = field.getBoolean(obj);
writeBoolean(x);
}
});
Primatives.put(byte.class,
new FieldGetAction()
{
public void get(Object obj, Field field) throws IllegalAccessException, IOException
{
byte x = field.getByte(obj);
writeByte(x);
}
});
Primatives.put(short.class,
new FieldGetAction()
{
public void get(Object obj, Field field) throws IllegalAccessException, IOException
{
short x = field.getShort(obj);
writeShort(x);
}
});
Primatives.put(int.class,
new FieldGetAction()
{
public void get(Object obj, Field field) throws IllegalAccessException, IOException
{
int x = field.getInt(obj);
writeInt(x);
}
});
Primatives.put(long.class,
new FieldGetAction()
{
public void get(Object obj, Field field) throws IllegalAccessException, IOException
{
long x = field.getLong(obj);
writeLong(x);
}
});
Primatives.put(char.class,
new FieldGetAction()
{
public void get(Object obj, Field field) throws IllegalAccessException, IOException
{
char x = field.getChar(obj);
writeChar(x);
}
});
Primatives.put(float.class,
new FieldGetAction()
{
public void get(Object obj, Field field) throws IllegalAccessException, IOException
{
float x = field.getFloat(obj);
writeFloat(x);
}
});
Primatives.put(double.class,
new FieldGetAction()
{
public void get(Object obj, Field field) throws IllegalAccessException, IOException
{
double x = field.getDouble(obj);
writeDouble(x);
}
});
Primatives.put(String.class,
new FieldGetAction()
{
public void get(Object obj, Field field) throws IllegalAccessException, IOException
{
String x = (String) field.get(obj);
writeUTF(x);
}
});
} catch(Exception e)
{
Log.e("SOb", Log.getStackTraceString(e));
}
ArrayPrimatives = new HashMap<Class, ArrayGetAction>();
try
{
ArrayPrimatives.put(boolean.class,
new ArrayGetAction()
{
public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
boolean x = Array.getBoolean(obj, index);
writeBoolean(x);
}
});
ArrayPrimatives.put(byte.class,
new ArrayGetAction()
{
public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
byte x = Array.getByte(obj, index);
writeByte(x);
}
});
ArrayPrimatives.put(short.class,
new ArrayGetAction()
{
public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
short x = Array.getShort(obj, index);
writeShort(x);
}
});
ArrayPrimatives.put(int.class,
new ArrayGetAction()
{
public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
int x = Array.getInt(obj, index);
writeInt(x);
}
});
ArrayPrimatives.put(long.class,
new ArrayGetAction()
{
public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
long x = Array.getLong(obj, index);
writeLong(x);
}
});
ArrayPrimatives.put(char.class,
new ArrayGetAction()
{
public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
char x = Array.getChar(obj, index);
writeChar(x);
}
});
ArrayPrimatives.put(float.class,
new ArrayGetAction()
{
public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
float x = Array.getFloat(obj, index);
writeFloat(x);
}
});
ArrayPrimatives.put(double.class,
new ArrayGetAction()
{
public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
double x = Array.getDouble(obj, index);
writeDouble(x);
}
});
ArrayPrimatives.put(String.class,
new ArrayGetAction()
{
public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException
{
String x = (String) Array.get(obj, index);
writeUTF(x);
}
});
} catch(Exception e)
{
Log.e("SOb", Log.getStackTraceString(e));
}
}
class State
{
public ArrayList<Object> OStack = new ArrayList<Object>();
public long currentId = 1;
public HashMap<Object, Long> References = new HashMap<Object, Long>();
}
public void writeObject(Object A) throws IOException, NotSerializableException
{
final State state = new State();
state.OStack.add(0, A);
LinkedList<Object> ForStack = new LinkedList<Object>();
while (!(state.OStack.size() == 0))
{
Object Current = state.OStack.get(0);
state.OStack.remove(0);
if (((Serializable) Current) == null)
{
throw new NotSerializableException();
}
//Type C = Current.getClass();
Class C = Current.getClass();
Log.i("SOb", "placing #"+Long.toString(state.currentId)+" of "+C.getCanonicalName()+" on graph");
state.References.put(Current, state.currentId);
state.currentId++;
ForStack.add(Current);
if (C.isArray())
{
//Array array = (Array) Current;
Class Ctype = C.getComponentType();
if (ArrayPrimatives.keySet().contains(Ctype) == false)
{
for (int I=0; I<Array.getLength(Current); I++)
{
Object o = Array.get(Current, I);
if ((o != null) && (state.References.keySet().contains(o) == false))
{
if (state.OStack.contains(o) == false) state.OStack.add(state.OStack.size(), o);
}
}
}
} else
{
for (Class Cur = C; Cur != null; Cur = Cur.getSuperclass())
{
Field[] fields = Cur.getDeclaredFields();
for (Field f : fields)
{
if (Modifier.isStatic(f.getModifiers()))
{
continue;
}
f.setAccessible(true);
if (f.isAccessible() == false)
{
// Log.i("SOb", " isAccessible = false");
continue;
}
Class type = f.getType();
//Log.i("SOb", " field \""+f.getName()+"\" of "+type.getCanonicalName());
if (Primatives.keySet().contains(type) == false)
{
try
{
Object o = f.get(Current);
if ((o != null) && (state.References.keySet().contains(o) == false))
{
if (state.OStack.contains(o) == false) state.OStack.add(state.OStack.size(), o);
}
} catch (IllegalAccessException e)
{
Log.e("SOb", Log.getStackTraceString(e));
}
}
}
}
}
}
writeLong(state.References.size());
for (Object O : ForStack )
{
Serializable s = (Serializable) O;
// if (s != null)
{
Class cl = O.getClass();
String name = cl.getName();
writeUTF(name);
if (cl.isArray())
{
Class components = cl.getComponentType();
ArrayGetAction action;
//Array array = (Array) O;
if (ArrayPrimatives.keySet().contains(components))
{
action = ArrayPrimatives.get(components);
} else
{
action = new ArrayGetAction()
{
public void get(Object array, int index) throws ArrayIndexOutOfBoundsException, IOException
{
Object O = Array.get(array, index);
if (O==null) writeLong(0);
else writeLong(state.References.get(O));
}
};
}
int length = Array.getLength(O);
writeInt(length);
for (int I=0; I<length; I++)
{
action.get(O, I);
}
} else
{
for (Class Cur = cl; Cur != null; Cur = Cur.getSuperclass())
{
Field[] fields = Cur.getDeclaredFields();
for (Field F : fields)
{
Class FieldType = F.getType();
F.setAccessible(true);
if (F.isAccessible() && (Modifier.isStatic(FieldType.getModifiers())))
{
FieldGetAction action;
//Array array = (Array) O;
if (Primatives.keySet().contains(FieldType))
{
action = Primatives.get(FieldType);
} else
{
action = new FieldGetAction()
{
public void get(Object obj, Field index) throws IllegalAccessException, IOException
{
Object O = index.get(obj);
if (O==null) writeLong(0);
else writeLong(state.References.get(O));
}
};
}
try
{
action.get(O, F);
} catch (IllegalAccessException e)
{
Log.e("SOb", Log.getStackTraceString(e));
}
}
}
}
}
}
}
}
}
答案 7 :(得分:0)
我有类似的问题。经过多次打猎,我发现了一个Kryo叉子,用于处理深层嵌套的物体。通过https://github.com/EsotericSoftware/kryo/issues/103,克隆和mvn clean install
https://github.com/romix/kryo/tree/kryo-2.23-continuations。它目前是com.esotericsoftware.kryo:kryo:2.23-SNAPSHOT
。