2014-01-14 4 views
0

Как я могу ссылаться на объект, который, я уверен, будет сериализован, но я не хочу, чтобы он был сериализован через эту ссылку?Как сохранить ссылку на объект Serialized в Java?

Чтобы сделать его более ясным, У меня есть Network, который содержит список Nodes каждого Node содержит список Connections, то Connection содержит ссылку на другие Nodes.

Проблема заключается в том, когда я пытаюсь сериализацию вид большой Network это приводит к StackOverflowError, ситуация, что я предполагаю, что вызывает это следующее:

  • Сериализация начинается с Network и пытается сериализовать первый Node
  • Затем он пытается сериализовать первое соединение, которое содержит ссылку на другой узел
  • он пытается сериализовать следующий Node и так далее, и сериализация рекурсия идет через в ч все узлы, вызывающие переполнение
  • Если ссылки в Connection помечены как transient нет никаких проблем в сериализации, но тогда ссылки = null после десериализации

Ниже приведен пример, который воспроизводит проблему

Network.java

import java.io.Serializable; 
import java.util.ArrayList; 

public class Network implements Serializable { 
    private static final long serialVersionUID = 1399116563470735156L; 

    ArrayList<Layer>layers; 

    public Network() { 
     layers= new ArrayList<Layer>(); 
    } 

    //connect each layer to next layer 
    public void connectAllLayers(){ 
     for (int i = 0; i < layers.size()-1; i++) { 
      layers.get(i).connectTo(layers.get(i+1)); 
     } 
    } 
} 

слоя. Java

import java.io.Serializable; 
import java.util.ArrayList; 


public class Layer implements Serializable{ 
    private static final long serialVersionUID = -5519150448729707106L; 

    public ArrayList<Node>nodes; 

    public Layer(int nodeCount) { 
     nodes = new ArrayList<Node>(); 
     for (int i = 0; i < nodeCount; i++) { 
      nodes.add(new Node()); 
     } 
    } 

    //connect all nodes in a layer to all nodes in the other layer 
    public void connectTo(Layer layer){ 
     for (Node myNode : nodes) { 
      for (Node toNode : nodes) { 
       myNode.connectTo(toNode); 
      } 
     } 
    } 
} 

Node.java

import java.io.Serializable; 
import java.util.ArrayList; 


public class Node implements Serializable{ 
    private static final long serialVersionUID = 6323513316304801012L; 

    public ArrayList<Connection>connections; 
    public double x,y,z,a,b,c;//some variables to simulate memory usage 

    public Node() { 
     connections = new ArrayList<Connection>(); 
     x=15; 
    } 

    public void connectTo(Node node){ 
     Connection connection = new Connection(this, node); 
     this.connections.add(connection); 
     node.connections.add(connection); 
    } 
} 

Connection.java

import java.io.Serializable; 

public class Connection implements Serializable { 
    private static final long serialVersionUID = 7578299749680304407L; 

    public Node from; 
    public Node to; 
    public double weight; 

    public Connection(Node from, Node to) { 
     this.from = from; 
     this.to = to; 
    } 
} 

Main.java

import java.io.*; 

public class Main { 

    public static void saveNetwork(Network net, String filename) { 
     try { 
      // Serialize data object to a file 
      ObjectOutputStream out = new ObjectOutputStream(
        new FileOutputStream(filename)); 
      out.writeObject(net); 
      out.close(); 
     } catch (IOException e) { 
     } 
    } 

    public static Network loadNetwork(String filename) { 
     Network net = null; 
     try { 
      FileInputStream door = new FileInputStream(filename); 
      ObjectInputStream reader = new ObjectInputStream(door); 
      net = (Network) reader.readObject(); 
      reader.close(); 
     } catch (Exception e) { 
      System.err.println(e.getMessage()); 
     } 
     return net; 
    } 

    public static void main(String[] args) { 
     Network net; 
     boolean load = false;//Change to true to load the saved object 

     if (!load) { 
      net = new Network(); 
      net.layers.add(new Layer(400)); 
      net.layers.add(new Layer(300)); 
      net.layers.add(new Layer(10)); 

      net.connectAllLayers(); 

      saveNetwork(net, "mynet"); 
     } else { 
      net = loadNetwork("mynet"); 
     } 
     Layer layer = net.layers.get(0); 
     Node node = layer.nodes.get(0); 
     Connection connection = node.connections.get(0); 
     System.out.println(connection.to.x); 
    } 

} 

Чтобы сделать вопрос более общим, можно ли каким-либо образом сериализовать график, как связанные классы классов, если есть список, содержащий ссылки на все узлы, не вызывая переполнения?

ответ

0

Java будет хорошо сериализовать графики, сохранив только ссылки на объекты, которые уже были сериализованы. Тем не менее, он использует рекурсию с помощью метода глубины, и ваш график очень глубокий (548 узлов до того, как я получил переполнение стека).

Сортируйте свои слои по глубине и сериализуйте их в порядке убывания глубины. Это предотвратит глубокую рекурсию при сериализации.

+0

Я полностью в курсе, что моя сеть слишком большая, оригинальная версия является Neural Network это должно быть так. Есть ли способ сделать это в стиле BFS? или предотвратить DFS через объекты соединения, но сохранить только ссылки? –

+0

Если вы можете каким-то образом создать список своих объектов («Список '), который упорядочен «самым глубоким первым», вы можете сначала сериализовать этот список, сразу же последовать за вашей сетью (в том же потоке). Когда сетевой объект сериализуется, все его записи слоя будут ссылками, а не полной сериализацией. Затем вы можете десериализовать список и сетевой объект и проигнорировать список. –

+0

Думаю, у меня есть идея, но в этом случае мне не нужно иметь этот «Список ». Все, что мне нужно сделать, это сериализация слоев назад, а не вперед, также есть другая вещь, все грани здесь двунаправленные, если они сохранены таким образом, не будет ни одного самого глубокого узла, но я думаю, что могу сделать его одним направлением во время сериализации , тогда, когда я десериализую, я восстановлю их снова, я попробую это сейчас. –

0

Я верю, что этот код будет работать для вас, позаботьтесь о его тщательном тестировании, если он используется для производства. Во-первых, он не ищет пользовательские процедуры сериализации на классах. Я считаю, однако, что это соответствует цели.

Он состоит из двух классов SequentialObjectOutputStream и SequentialObjectInputStream

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

          } 
         } 

        } 
       } 
      } 
     } 
    } 
} 

SequentialObjectInputStream

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

} 

SequentialObjectOutputStream

+0

Ваш код потрясающий, я должен признать, но я не могу точно понять, что он делает. В общем, я понял, что вы пересекаете объект в режиме BFS, и вы сохраняете ссылку на каждый объект, который вы сериализуете в HashMap, тогда вы его пишете. Можете ли вы в целом описать, как работает ваш метод? (возможно, некоторые комментарии или просто общее описание) –

+0

Ali, Мое извинения за задержку в моем обращении. Короче говоря, java имеет два основных режима хранения двоичных значений: поля и массивы. Это означает, что вы можете использовать оба метода. Он записывает имя значимого класса в поток. Затем он получает доступ к списку объектов Field из класса. Использование аксессуаров, закодированных в Primatives и ArrayPrimatives, вызывается действие, которое обрабатывает IO для обоих. Методы ввода-вывода, которые ставят/получают объект, избегают рекурсии за счет использования списков, поэтому ссылки устанавливаются и готовы к немедленному написанию. для чтения их - это исправление, которое имеет место последним – RofaMagius

Смежные вопросы