Java泛型 - 未经通配符处理的类型与非泛型类型有何不同?

5
在Java泛型上下文中,裸类型是泛型类型的非参数化调用。他们还说任何非泛型类型都不是裸类型。
我困惑的是,为什么他们说非泛型类型不是裸类型?它与泛型类型的非参数化调用有什么不同。请看以下两个案例。
案例1:
class A<T>{

}
A a = new A(); //Raw type

案例2:

class A{

}
A a = new A();//Non-generic type

如果变量“a”在两种情况下的行为完全相同,为什么他们说case[1]是原始类型而case[2]不是?

行为上基本上是一样的。语义上则有很大不同。 - Oliver Charlesworth
你可以阅读 https://dev59.com/m3E85IYBdhLWcg3wdDIM - Ortomala Lokni
@Ortomala Lokni 谢谢你提供的链接。它说:“本质上,原始类型的行为就像在引入泛型之前一样”,这可能告诉我,我的变量“a”在两种情况下都会表现得完全相同。如果是这样,请回答这个问题。我会接受它。但即便如此,我仍然想知道,在这种情况下,他们为什么说非泛型类型不是原始类型?所有非泛型类型也是原始类型,这样说有什么问题吗? - user4710520
一个很好的资源,详细介绍了泛型:Java Generics FAQ - Jesper
3个回答

3
原始类型的概念仅适用于泛型类型,因为原始类型被认为与泛型类型具有赋值兼容性,但进行此类赋值会打开泛型类型本应保证的类型安全漏洞。例如,考虑一个方法void workWith(A<Integer> a)。您将被允许传入a变量,这会导致类型安全问题。由于非泛型类型不会遭受此类问题,因此它们不被称为“原始类型”。

@SureshKumarKV:使用原始类型会给你一个警告,而非泛型类型的使用则不会。 - newacct

1

JLS所述:

非泛型类或接口类型不是原始类型。

您可以从语法层面感受到区别:

如果我们有参数化类:

class A<X> {
   class B<Y> {
      Y y;
   }
}

那么仅使用A名称类型或B名称类型并不是非泛型类型,它们是原始类型,这会影响您如何访问它们:

所有这些构造都会导致编译时错误:

A<Integer>.B ab = null;
A.B<Integer> ab = null;

我同意。 我更感兴趣的是要知道变量“a”在我给出的两种情况下是否有不同的行为。 - user4710520

0

原始类型与泛型类型的边界和类型擦除有关。如果你有 ArrayList<? extends Shape>,那么边界类型是 Shape,在编译时将成为原始类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接