Java 如果我从泛型类派生非泛型类,类型会发生什么变化?
比如说,我有一个普通的POJO,叫做Java 如果我从泛型类派生非泛型类,类型会发生什么变化?,java,generics,serialization,Java,Generics,Serialization,比如说,我有一个普通的POJO,叫做Person。现在,由于类型擦除,ArrayList的实例在运行时将具有类型ArrayList。如果此实例通过某些库(如Gson)进行序列化/反序列化,则所需的序列化对象不是ArrayList,当然,除非我们专门提供类型标记。 现在,问题来了。如果我创建另一个类(比如Persons),会发生什么情况,如下所示: public class Persons extends ArrayList<Person> { } 公共类人员扩展ArrayList{
Person
。现在,由于类型擦除,ArrayList
的实例在运行时将具有类型ArrayList
。如果此实例通过某些库(如Gson)进行序列化/反序列化,则所需的序列化对象不是ArrayList
,当然,除非我们专门提供类型标记。现在,问题来了。如果我创建另一个类(比如
Persons
),会发生什么情况,如下所示:
public class Persons extends ArrayList<Person> {
}
公共类人员扩展ArrayList{
}
类型信息会保留在这里吗?反序列化机制是否能够推断类型确实是ArrayList
,而不是原始类型ArrayList
类型信息会保留在这里吗
对,;例如,这:
final ParameterizedType superTypeOfPersons =
(ParameterizedType) Persons.class.getGenericSuperclass();
System.out.println(superTypeOfPersons.getActualTypeArguments()[0].getSimpleName());
将打印个人
反序列化机制是否能够推断类型确实是ArrayList
,而不是原始类型ArrayList
它可能会这样做,但这并不一定意味着它会这样做;这不是一件小事。如果您需要支持一组特定的序列化框架,那么您应该对每一个框架进行测试。我认为Desiralization将为您提供类型信息,您可以直接将其转换为
Person
尝试序列化和反序列化,也许?我不确定是否理解您的问题。如果你反序列化一个Persons
对象,那么它的类就不是Persons
,而不是ArrayList
或ArrayList
?@OrestSavchak我认为它不会给出像add(personp)这样的方法,除非他重写add方法。参考示例:@VirajNalawade,yeap,在编译之前它是正确的,但在运行时您没有泛型,泛型被替换为所选类型或对象。读这篇文章。这与我所经历的是一致的。有可能这样做的好处。那么,我们在这里是在作弊吗?据我所知,类型擦除是为了保持向后兼容性。这是如何影响的?这(功能上)离具体化的泛型有多远?就像在C#中一样。@akshay2000:不清楚你的问题是关于什么的。正如该答案所述,类型信息可用。这并没有改变您仍然可以将castPersons
键入原始类型ArrayList
并将Object
s添加到其中的事实,除非Persons
重写所有允许添加/设置元素的方法。@akshay2000:Type erasure意味着泛型类型的实例不知道类型参数是什么;例如,new ArrayList()
和new ArrayList()
创建相同的实例。这对于向后兼容性非常重要,因为这意味着您可以使用Java-5之前的库创建的ArrayList
,并将其安全地视为ArrayList
(前提是它实际上是Person
-s的ArrayList
)。但这不适用于这里。@ruakh这就是我在这里缺少的东西。因此,在我的理解中,如果我创建ArrayList
,即使是Java-5之前的库也能很好地处理它(因为它在运行时只是ArrayList
)。然而,pesron
也会这样吗?因为它肯定是ArrayList
,而不仅仅是ArrayList
,而且我不认为pre-5 java理解什么是ArrayList
@akshay2000:Java类文件包含版本号。如果程序的一部分是由支持泛型(Java 5或更高版本)的编译器编译的,那么类文件版本将至少为49,这意味着不支持泛型(Java 1.4或更低版本)的JVM甚至不愿意加载该类。(你会得到一份工作。)