2015-06-01 125 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