2016-02-25 57 views
1

原始較小我有它接受一個對象,並把它變成一個字節數組的函數:陣列的比原始對的ObjectOutputStream

public static byte[] serialize(Object obj) throws IOException { 
    try(ByteArrayOutputStream b = new ByteArrayOutputStream()){ 
     try(ObjectOutputStream o = new ObjectOutputStream(b)){ 
      o.writeObject(obj); 
     } 
     return b.toByteArray(); 
    } 
} 

當我使用上的原始類型此功能,輸出最終被大於相同基元的單一數組。

public static void main (String[] args) throws java.lang.Exception 
{ 
    System.out.format("byte single: %d, array: %d\n", 
      serialize((byte) 1).length, serialize(new byte[]{1}).length); 

    System.out.format("short single: %d, array: %d\n", 
      serialize((short) 1).length, serialize(new short[]{1}).length); 

    System.out.format("int  single: %d, array: %d\n", 
      serialize((int) 1).length, serialize(new int[]{1}).length); 

    System.out.format("float single: %d, array: %d\n", 
      serialize((float) 1).length, serialize(new float[]{1}).length); 

    System.out.format("double single: %d, array: %d\n", 
      serialize((double) 1).length, serialize(new double[]{1}).length); 

} 

這將產生:

byte single: 75, array: 28 
short single: 77, array: 29 
int  single: 81, array: 31 
float single: 79, array: 31 
double single: 84, array: 35 

這到底是怎麼回事?爲什麼數組更小?這是一個Ideone for the issue

回答

1

ObjectOutputStream正在處理原始數組不同於其他對象。你是不是序列化的原語,但反對,因爲他們得到這樣的序列化之前int盒裝成爲Integer

對於數組,ObjectOutputStream剛剛寫入以下內容(我用double爲例)

1 byte // to mark it as array 
22 bytes // for the class description 
4 bytes // the length of the array 
8 bytes // for the double (would be array.length * 8) is you have more elements 

這使得35個字節正如你在實驗中觀察到的那樣。

對於其他對象 - 像盒裝原語 - 它使用更多的空間,因爲它必須存儲更多的元信息。它必須存儲它們對象的類型,並且對於每個成員它必須存儲相同的信息 - 所以它有點遞歸。

如果您真的想詳細瞭解正在進行的操作,建議您閱讀ObjectOutputStreamsource code

1

這是因爲Java對數組使用不同的編碼效率更高。如果你序列化了一個Byte,它會寫入你有一個對象(你可能會在後面提到,所以它會記錄一個id),它有一個類java.lang.Byte(它也有一個id),它有一個父類java.lang.Number(也帶有一個id) ,它沒有字段,字節有一個字段被稱爲「值」(這是一個帶有id的字符串),字節的值只使用一個字節。

一個字節[]的內部名稱爲[B,它沒有字段父項,所以它更短。