2014-06-10 5 views
6

Что происходит во время сериализации в java, если два объекта refrences указывают на один и тот же сериализуемый объект? Сохраняет ли Serializable Objects дважды?
, например:Что происходит во время сериализации в java, если два объекта refrences указывают на один и тот же сериализуемый объект?

class King implements java.io.Serializable { 
     private String name="Akbar"; 
    } 

    class Kingdom implements java.io.Serializable { 
     King goodKing=new King(); 
     King badKing=goodKing; 
    } 

    public class TestSerialization { 
     public static void serializeObject(String outputFileName, 
              Object serializableObject) throws IOException { 
      FileOutputStream fileStream=new FileOutputStream(outputFileName); 
      ObjectOutputStream outStream=new ObjectOutputStream(fileStream); 
      outStream.writeObject(serializableObject); 
      outStream.close(); 
     } 

     public static void main(String[] args) { 
      Kingdom kingdom=new Kingdom(); 
      try { 
       TestSerialization.serializeObject("Kingdom1.out", kingdom); 
      }catch(IOException ex) { 
       ex.getMessage(); 
      } 
     } 
    } 

Теперь, будь то сохраняется состояние только один объект для обоих goodKing и badKing refrences или объект King спасаются дважды?

+1

Вы пытались сохранить класс с одной и двумя ссылками и сравнили размер файла результата? – Smutje

+1

Попытайтесь десериализовать Королевство и посмотрите, есть ли goodKing и badKing для одного и того же Короля. Если они есть, то, имея одного Короля в Царстве, достаточно сделать десериализацию Царства. Из этого можно предположить, что сохраняется только одно состояние объекта. – fajarkoe

+0

@Smutje Сгенерированный файл всегда показывает размер 1KB –

ответ

7

Документация ObjectOutputStream говорит, что происходит:

Механизм сериализации объекта по умолчанию записывает класс объекта, класс подписи и значения всех без переходных и нестатических полей. Ссылки на другие объекты (за исключением временных или статических полей) также заставляют записывать эти объекты. Несколько ссылок на один объект кодируются с использованием механизма обмена ссылками, так что графики объектов могут быть восстановлены в той же форме, что и при написании оригинала.

(курсив мой)

Например, если у вас есть несколько ссылок на один объект, когда граф разводится, вы в конечном итоге с несколькими ссылками на одной реконструированной версии этого объекта, а не ссылки на несколько эквивалентных экземпляров.

Конечно, если сериализуемый контейнер реализует другой механизм, поведение продиктовано этим механизмом, а не стандартным.

Так, например, если у нас есть Thing и Test:

Thing.java:

import java.io.*; 
import java.util.*; 

public class Thing implements Serializable { 
    private Map<String,String> map1; 
    private Map<String,String> map2; 

    public Thing() { 
     this.map1 = new HashMap(); 
     this.map2 = this.map1; // Referring to same object 
    } 

    public void put(String key, String value) { 
     this.map1.put(key, value); 
    } 

    public boolean mapsAreSameObject() { 
     return this.map1 == this.map2; 
    } 
} 

Test.java:

import java.io.*; 

public class Test implements Serializable { 

    public static final void main(String[] args) { 
     try 
     { 
      // Create a Thing 
      Thing t = new Thing(); 
      t.put("foo", "bar"); 

      // Write it out 
      ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("foo")); 
      os.writeObject(t); 
      os.close(); 
      os = null; 

      // Read it in 
      Thing t2; 
      ObjectInputStream is = new ObjectInputStream(new FileInputStream("foo")); 
      t2 = (Thing)is.readObject(); 
      is.close(); 
      is = null; 

      // Same underlying map for both properties? 
      System.out.println("t2.mapsAreSameObject? " + t2.mapsAreSameObject()); 
     } 
     catch (Exception e) 
     { 
      System.out.println("Exception: " + e.getMessage()); 
     } 
    } 
} 

И запустить java Test, мы получаем:

t2.mapsAreSameObject? true

... потому что оба из Thing членов, map1 и map2 в конечном итоге указывая на один HashMap экземпляр.

+0

Вы хотите сказать, что независимо от отсутствия рефлексов для одного объекта, только одна копия этого объекта будет сохранена во время сериализации и во время сериализации, каждое подтверждение этого единственного объекта будет восстановлено назад, как в исходном классе. –

+0

@AmiteshRai: Верно. Вернее, это то, что говорит документация. :-) И снова, это с сериализацией по умолчанию; если контейнер реализует собственную сериализацию, он может сделать что-то еще (хотя делать что-то еще было бы странно и удивительно). –

+0

@ T.J.Crowder - Я не совсем понимаю. Почему в процессе сериализации появляются ссылки? Сериализация - это более или менее сброс объекта. Сколько ссылок на объект не имеет значения. правильно? – TheLostMind

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