2012-05-30 53 views
3
public static void main(String[] args) throws Exception { 
    Socket socket = new Socket("127.0.0.1", 2345); 

    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 
    Map<Integer, Integer> testMap = new HashMap<Integer, Integer>(); 

    testMap.put(1,1); 
    oos.writeObject(testMap); 
    oos.flush(); 

    testMap.put(2,2); 
    oos.writeObject(testMap); 
    oos.flush(); 

    oos.close(); 
} 


public static void main(String[] args) throws Exception { 
    ServerSocket ss = new ServerSocket(2345); 
    Socket s = ss.accept(); 
    ObjectInputStream ois = new ObjectInputStream(s.getInputStream()); 

    System.out.println((HashMap<Integer, Integer>) ois.readObject()); 
    System.out.println((HashMap<Integer, Integer>) ois.readObject()); 

    ois.close; 
} 

上面的代碼來自兩個文件。 當運行它們,控制檯打印相同的結果:發送更改的hashmap,但使用ObjectOutputStream和ObjectInputStream獲得相同的一個

{1=1} 
{1=1} 

怎麼能這樣呢?

回答

6

一個ObjectOutputStream記住它已經寫的對象和反覆寫入只會輸出指針(而不是再次的內容)。這保留了對象標識並且對於循環圖是必需的。

那麼你流包含基本上是:

  • 指針:與內容{111}:

    • HashMap中的 「再次HashMap中的」

    你需要使用一個新的HashMap實例在你的情況。

  • +1

    您也可以重置ObjectOutputStream(而不必創建一個新的hashmap對象)。 –

    +0

    謝謝你,我想知道這是否會發生在其他的數據結構? – JustFF

    +0

    當然,出現這種情況與所有對象。 – Thilo

    2

    正如Thilo已經說過,一個ObjectOutputStream保持的東西它已經寫入高速緩存。您可以使用一個新的地圖,因爲他暗示,或清除緩存。

    調用調用之間ObjectOutputStream.resetwriteObject將清除緩存並給你原先預期的行爲。

    public static void main(String[] args) throws IOException, 
         ClassNotFoundException { 
        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
        try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { 
         HashMap<Integer, Integer> foo = new HashMap<>(); 
         foo.put(1, 1); 
         oos.writeObject(foo); 
         // oos.reset(); 
         foo.put(2, 2); 
         oos.writeObject(foo); 
        } 
    
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 
        try (ObjectInputStream ois = new ObjectInputStream(bais)) { 
         System.out.println(ois.readObject()); 
         System.out.println(ois.readObject()); 
        } 
    } 
    
    相關問題