【问题标题】:Why doesn't autoboxing work in this case with generics? [duplicate]为什么在这种情况下自动装箱不适用于泛型? [复制]
【发布时间】:2012-07-10 19:14:42
【问题描述】:

可能重复:
Java: Array of primitive data types does not autobox

我最近一直在做一些 Java(主要是对我在大学所做的事情的回顾,因为我目前的工作根本不涉及任何 Java),而从未正确地介绍给我们的一件事是泛型。

我一直在 Oracle Java 网站上做泛型教程,但我被以下我修改了一下的示例难住了:

public static <Integer extends Comparable<Integer>> int countGreaterThan(Integer [] anArray, Integer elem) {
    int count = 0;
    for (Integer e : anArray)
        if (e.compareTo(elem) > 0)
            ++count;
        return count;
}

我使用这种方法将一个整数数组与以下整数进行比较:

Integer [] numarr = {1, 2, 3, 4 , 5};
Integer num = new Integer(5);

int count = Util.countGreaterThan(arrnum, num);

这似乎工作正常,但是如果我传递一个原始数组和一个原始 int,它不会:

int [] arrnum = {1, 2, 3, 4 , 5};
int othernum = 3;

int count = Util.countGreaterThan(arrnum, othernum);

编译器抱怨:

method countGreaterThan in class Generics.Util 
cannot be applied to given types;
required: Integer[],Integer
found: int[],int
reason: no instance(s) of type variable(s) 
Integer exist so that argument type int conforms to formal parameter type Integer

教程似乎非常坚持认为 Java 将始终根据需要自动装箱/取消装箱对象和原语,但在这种特殊情况下它不会这样做,我错过了什么?

还有什么是尽可能概括这种比较方法的好方法?如果我使用 T 而不是 Integer,那么它会寻找一个 T 对象,而不是我传递给它的任何东西。

如果这篇文章令人困惑,并且我似乎对我上面谈到的东西一无所知,我深表歉意,只是我主要是作为一名 perl 程序员工作(也不是特别有经验的程序员)并且在那里进行概括作为一个小问题(由于缺乏类型强制)。

提前致谢!

【问题讨论】:

  • 使用Integer 作为类型变量是个很糟糕的主意

标签: java generics object integer


【解决方案1】:

据我所知,下面的代码似乎可以工作:

public static <Integer extends Comparable<Integer>> int countGreaterThan(Integer [] anArray, Integer elem) {
    int count = 0;
    for (Integer e : anArray) {
        if (e.compareTo(elem) > 0)
            ++count;
        return count;
}

虽然我收到了警告"The type parameter Integer is hiding the type Integer"。请参阅@ErichSchreiner 的回答,了解为什么自动装箱在这里不起作用。

您的方法的一个很好的概括是:

public static <T extends Comparable<? super T>> int countGreaterThan(T[] anArray, T elem) {
    int count = 0;
    for (T e : anArray) {
        if (e.compareTo(elem) > 0) {
            ++count;
        }
    }
    return count;
}

您真正关心的是anArrayelem 具有相同类型的元素,并且与它自己的类型相当。

【讨论】:

  • 您在解释自动装箱问题方面做得更好,添加了参考。
  • 为获得最佳效果,请使用&lt;T extends Comparable&lt;? super T&gt;&gt;
  • @newacct:好点,已编辑。
【解决方案2】:

countGreaterThan() 的声明隐藏了内置类型 Integer。为了澄清,考虑稍微修改的版本:

public static <I extends Comparable<I>> int countGreaterThan(I [] anArray, I elem) {
    int count = 0;
    for (I e : anArray)
        if (e.compareTo(elem) > 0)
            ++count;
        return count;
}

现在应该很明显,您的第二次呼叫尝试无法正常工作,因为那里无法完成自动装箱。要使泛型起作用,您需要提供对象,而不是原语。

【讨论】:

  • 啊哈,谢谢!我假设因为我可以声明一个具有 Integer 返回类型的普通方法,然后毫无问题地将原语传递给它,所以我可以对泛型做同样的事情。我还尝试将 Generic 类传递给 count 方法(类似于public class Box&lt;T extends Integer&gt;),但是失败并显示:` required: T[],T found: Generics.Box[],Generics.Box reason: inferred type does不符合声明的界限`假设我不能将泛型类传递给 countGreaterThan(以 作为签名)是否安全?谢谢! @Keppil
猜你喜欢
  • 1970-01-01
  • 2013-07-22
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-03
  • 2015-10-26
  • 2016-03-24
相关资源
最近更新 更多