2015-06-01 172 views
3

讓我們說,我有一個通常叫做Person的POJO。現在,由於類型擦除,ArrayList<Person>的實例在運行時將具有類型ArrayList。如果這個實例通過像Gson這樣的庫進行序列化/反序列化,那麼desirialized對象不是ArrayList<Person>,除非我們特別提供類型標記。
現在,這是問題。如果我創建另一個類,會發生什麼(比如Persons)如下:如果我從泛型類派生非泛型類,會發生什麼類型?

public class Persons extends ArrayList<Person> { 
} 

將類型信息被保存在這裏?反序列化機制能夠推斷出類型確實是ArrayList<Person>而不是原始類型ArrayList

+0

我認爲desirialization會給你類型信息,你可以直接轉換爲'Person' – Babel

+0

嘗試序列化和反序列化它,也許? –

+0

我不知道我理解你的問題。如果反序列化一個Persons對象,那麼它不是它的類Persons而不是ArrayList 或ArrayList? – sprinter

回答

0

這裏的類型信息會被保存嗎?

是的;例如:

final ParameterizedType superTypeOfPersons = 
    (ParameterizedType) Persons.class.getGenericSuperclass(); 
System.out.println(superTypeOfPersons.getActualTypeArguments()[0].getSimpleName()); 

將打印Person

是反序列化機制能夠推斷出類型確實是ArrayList<Person>而不是原始類型ArrayList

它可能可以這樣做,但是,這並不一定意味着它確實這樣做;這不是一件微不足道的事情。如果您需要支持一系列特定的序列化框架,那麼您應該對每個框架進行測試。

+0

這與我所經歷的內容一致。 *有可能*這樣做的好處。那麼,我們在這裏欺騙類型擦除?據我所知,類型擦除是爲了保持向後兼容性。這是如何影響的?這個(功能上)來自於泛化的泛型 - 就像在C#中一樣。 – akshay2000

+0

@ akshay2000:目前尚不清楚你的問題是關於什麼。如該答案所述,類型信息可用。這並沒有改變任何事情,即你仍然可以將'Persons'強制轉換爲原始類型'ArrayList'並向其中添加'Object's,除非'Persons'覆蓋了所有允許添加/設置元素的方法。 – Holger

+0

@ akshay2000:類型擦除意味着泛型類型的實例不知道類型參數是什麼;例如'new ArrayList ()'和'new ArrayList()'創建相同的實例。這對於向後兼容性很重要,因爲這意味着你可以使用一個由Java-5之前的庫創建的'ArrayList'並將其安全地視爲一個'ArrayList '(假設它實際上是一個'Person'-s的'ArrayList')。但這並不適用於此。 – ruakh