Java泛型中的默认类型(如果未指定)

Java泛型中的默认类型(如果未指定),java,generics,Java,Generics,我不明白,如果没有指定类型,为什么Java泛型会出现以下情况。假设我们有一个简单的类: public class NumberList<T extends Number> extends ArrayList<T> { } 为什么列表迭代器现在返回对象?它是否应该默认为“最低”类(数字)?如果没有指定,我可以强制它这样做吗?NumberList是原始类型。不应使用原始类型,并且只允许与在将泛型引入语言之前编写的代码兼容 原始类型的工作方式是替换方法参数中的

我不明白,如果没有指定类型,为什么Java泛型会出现以下情况。假设我们有一个简单的类:

public class NumberList<T extends Number> extends ArrayList<T> {        
}

为什么列表迭代器现在返回对象?它是否应该默认为“最低”类(数字)?如果没有指定,我可以强制它这样做吗?

NumberList
是原始类型。不应使用原始类型,并且只允许与在将泛型引入语言之前编写的代码兼容

原始类型的工作方式是替换方法参数中的所有类型,并通过擦除返回类型。如果
T扩展了Number
,则
T
的擦除就是
Number
,但至关重要的是
中的所有类型信息都被擦除过程忽略。在这种情况下,
list
的作用就像
iterator()
返回普通的
iterator
而不是
iterator
(请记住,增强的
for
循环实际上只是使用
迭代器的语法糖)

有趣的是,以下内容确实可以编译:

NumberList list = new NumberList();
list.add(5);
Number a = m.get(0);
这是因为
get
返回
T
,而
T
的擦除是
Number
。如果
T
被视为
Number
,那么
Iterator
应该被视为
Iterator
,但是由于我们被简单地建议永远不要使用原始类型,因此尽可能地保持规则的简单是有意义的(即使它们有点奇怪)


关于这个主题的标准问题是。

NumberList
是一种原始类型,而原始类型具有传染性。如果引用原始类型,则其所有方法也适用于原始类型

特别是,这意味着for循环所依赖的
Iterator Iterator()
方法(基于NumberList是Iterable)变为
Iterator Iterator()
——它返回原始迭代器类型。Iterable的擦除是对象,而不是数字

换句话说,从
的角度考虑一下这是什么样子。对于泛型:

Iterable<Number> implicitIterable = list;
for (Number n: implicitIterable) ...

x instanceof Object
适用于任何类。我猜类型签名是类似的(如果不是完全等效的话)
加上一个用于传染的单词。这绝对是我见过的最好的表达方式。
NumberList list = new NumberList();
list.add(5);
Number a = m.get(0);
Iterable<Number> implicitIterable = list;
for (Number n: implicitIterable) ...
Iterable implicitIterable = list;
for (Number n: implicitIterable) ... // error! implicitIterable.next()
                                     // returns Object, not Number