Java 泛型输入类型与返回类型

Java generics input type vs returned type

我正在学习泛型,但有点困惑。 我对使用泛型的 class 的输入类型和返回类型之间的区别感到困惑。

   Stack<Integer> even = new Stack<>();
    // pushing values in stack
    even.push(0);
    even.push(2);

    System.out.println(even.pop().getClass().getSimpleName());
    System.out.println("pop => " + even.pop());

我们正在推入 0 和 2 的 int 值。 但是第一个打印语句将打印“Integer”。 如果堆栈以 Integer 作为其通用类型声明,为什么我们能够压入原始“int”? 如果我们可以推入原始“int”,为什么 pop() class 返回包装器 class “Integer”?

我显然对泛型有一些误解。

您不能将泛型声明为原始类型,因为它们不是 classes。它们是另一回事(当然是原始类型)。相反,您使用相应的包装器 class.

当您执行 push(int) 时,会通过 Integer#valueOf(int) 方法对包装器 class Integer 进行隐式转换。

stack.push(0);

由编译器转换,无需询问

stack.push(Integer.valueOf(0))

出于同样的原因,你可以这样做

Integer n = 3;

并且没有错误。

它的发生是因为一种叫做自动装箱的东西。

自动装箱是 Java 编译器在原始类型和它们对应的对象包装器 类 之间进行的自动转换。例如,将 int 转换为 Integer,将 double 转换为 Double,等等。如果转换以另一种方式进行,则称为拆箱。

最简单的例子:

Character ch = 'a';

这就是这里发生的事情:

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(i);

编译器从 i 创建一个 Integer 对象并将该对象添加到列表中。

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(Integer.valueOf(i));

你堆叠同样的东西。