2009-01-13 46 views
10

Tôi đang viết một ứng dụng bằng Java bằng cách sử dụng Swing. Tôi đang cố gắng thực hiện chức năng để lưu và tải các trạng thái mô phỏng cho lúc mô phỏng tôi đang chạy. Toàn bộ mô phỏng được giữ như một đối tượng, bị ngắt kết nối khỏi Swing. Tôi đang cố gắng sắp xếp hàng loạt lớp Mô phỏng của mình bằng mã này:StackOverflowError khi tuần tự hóa một đối tượng trong Java

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()); 
    } 
} 

Nhưng tôi nhận được lỗi sau (rất lớn).

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) 

Ai có thể cho tôi biết điều gì gây ra ngoại lệ này?

+0

Oh, và tất cả các mã của tôi có thể được tìm thấy ở đây: http://code.google.com/p/sensor-protocol-simulation/ Đoạn mã ví dụ được lấy từ GraphPanel.java ở phần view. – utdiscant

Trả lời

12

bài Thú vị từ Chen:

When debugging a stack overflow, you want to focus on the repeating recursive part

Trong trường hợp của bạn:

 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) 

Nếu bạn đi săn qua cơ sở dữ liệu theo dõi lỗi của bạn cố gắng để xem liệu đây có phải là vấn đề đã biết hay không, việc tìm kiếm các chức năng hàng đầu trên ngăn xếp không chắc để tìm bất cứ điều gì thú vị. Đó là bởi vì tràn ngăn xếp có xu hướng xảy ra tại một điểm ngẫu nhiên trong đệ quy; mỗi ngăn xếp tràn trông bề ngoài khác nhau từ mỗi khác ngay cả khi chúng là cùng một ngăn xếp tràn.

Khi bạn vượt qua được sự xáo trộn ban đầu, dấu vết ngăn xếp sẽ lắng xuống thành một mẫu lặp lại đẹp bao gồm các hàm x giống nhau lặp đi lặp lại.
Xác định sự bắt đầu của mẫu lặp lại không quan trọng, vì điểm bắt đầu sẽ khác nhau đối với từng sự cố, giống như cách ghi chú chính xác vượt quá phạm vi hát của bạn thay đổi từ sự cố đến lỗi.

Khi bạn đã xác định phần lặp lại, hãy chọn một hàm từ đó có phần bất thường và tìm kiếm nó trong your defect database.

For example, mặc định ArrayList serialization.

Đây GrahPanel bạn đề cập một Simulation đó đề cập đến Graph, với dài ArrayList khả năng của cảm biến và Edge ...

Java serialization giữ một kỷ lục của mọi đối tượng ghi vào một dòng suối. Nếu đối tượng tương tự được gặp phải lần thứ hai, chỉ một tham chiếu đến đối tượng đó được ghi vào luồng chứ không phải bản sao thứ hai của đối tượng; tham chiếu vòng tròn như vậy không phải là vấn đề ở đây.

Nhưng việc tuần tự có thể dễ bị tràn ngăn xếp đối với một số loại cấu trúc nhất định; ví dụ: danh sách được liên kết dài không có phương thức writeObject() đặc biệt nào sẽ được tuần tự bằng cách đệ quy viết từng liên kết. Nếu bạn có 100.000 liên kết, bạn sẽ cố gắng sử dụng 100.000 khung ngăn xếp và rất có thể không thành công với StackOverflowError.

Có thể xác định phương thức writeObject() cho lớp danh sách như vậy, khi liên kết đầu tiên được nối tiếp, chỉ cần đi vào danh sách và nối tiếp từng liên kết lặp lại; điều này sẽ ngăn chặn cơ chế đệ quy mặc định không được sử dụng.

1

Bạn có một số ArrayLists lồng nhau sâu sắc.

Tôi nghĩ rằng có lẽ nó chỉ đi sâu đầu tiên, và điều đó có nghĩa là nó sẽ cho cảm biến đáy, mà là quá sâu.

Có thể bạn có thể tạo cấu trúc tùy chỉnh với Bộ cảm biến bắt đầu bằng Bộ cảm biến dưới cùng?

Hoặc có thể bạn sẽ phải cung cấp tuần tự hóa của riêng mình để xử lý nó? http://java.sun.com/developer/technicalArticles/Programming/serialization/

0

Bạn nên tạo lớp chứa cho các đối tượng bạn muốn lưu trữ. Tôi sẽ không lưu trữ hoàn thành đối tượng này với tất cả logic bên trong.

Lưu trường đầu tiên theo trường để tìm phần tử lớn để lưu trữ theo cách đó. Hơn đặt điểm ngắt trong methode và xem xét phần tử trường. Phần tử có chứa các liên kết liên kết với nhau không?

2

Bạn nên xem xét lại các phương thức writeObject/readObject của lớp Mô phỏng để chỉ tuần tự hóa dữ liệu có liên quan (hoặc không phải toàn bộ cấu trúc đối tượng chứa) hoặc gắn thẻ tạm thời không được sắp xếp theo thứ tự. Bạn cũng có thể sử dụng giao diện Externalizable nếu cần.

BTW, bạn có thể muốn đọc số này interesting article để bắt đầu.

0

Và sau khi bạn thực hiện tất cả những gì chỉ sử dụng XStream thay thế nếu bạn chỉ muốn lưu vào một tệp.

0

Run java với đống lớn

0

Mã này sẽ hoạt động như một mô hình, vì nó giải quyết vấn đề của stackoverflow trên serialization. Nó sử dụng bộ nhớ thay cho đệ quy. Mặc dù không phù hợp để được concidered phổ như một serializer, nó serializes và deserializes các lớp học nó đã được thử nghiệm với.

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)); 
           } 

          } 
         } 

        } 
       } 
      } 
     } 
    } 
} 
+0

Đó là rất nhiều mã, không có giải thích làm thế nào nó trả lời câu hỏi. Bạn có thể thêm một chút mô tả về những gì nó đang làm không? – andrewsi

+0

Trong khi serializing, 2 pass được sử dụng. Đầu tiên thêm tất cả các đối tượng duy nhất vào một danh sách đối tượng và tạo một chỉ mục cho từng đối tượng. Đợt thứ hai. nối tiếp một khung nhìn phẳng của đối tượng với chỉ mục được sử dụng thay cho giá trị của một trường hoặc giá trị mảng. Bằng cách này, khi danh sách đối tượng được xử lý, có một ánh xạ phẳng của đối tượng được tuần tự hóa và các tham chiếu của nó mà không sử dụng một writeObject đệ quy. – RofaMagius

Các vấn đề liên quan