如何解释泛型方法中的警告?

时间:2017-11-08 19:53:25

标签: java generics

你能帮我解释一下通用方法中的警告吗? 我遇到了this Oracle tutorial task并试图实施它:

  

编写通用方法以查找范围中的最大元素   列表的[开始,结束]。

这是我的第一个版本运行良好但编译时发出警告:

  

信息:java:C:\ Java \ bla \ bla使用未经检查或不安全的操作。

public static <T extends Comparable> T findMax2(List<T> list, int first, int second) {
    T max = list.get(first);
    for (int i = first+1; i < second; i++) {
        if (list.get(i).compareTo(max)>0) max = list.get(i);
    }
    return max;
}

然后我窥探了Collections.max方法,并以这种方式重写了我的方法(现在它编译时没有任何警告,也可以正常工作!):<​​/ p>

   public static <T extends Object & Comparable<? super T>> T findMax3(List<T> list, int first, int second) {
        T max = list.get(first);
        for (int i = first+1; i < second; i++) {
            if (list.get(i).compareTo(max)>0) max = list.get(i);
        }
        return max;
    }

问题是为什么?我的第一次尝试方法出了什么问题?为什么改进的版本会修复警告?

1 个答案:

答案 0 :(得分:2)

当你编译没有正确的泛型时,你应该得到这两个消息:

  

注意:Test.java使用未经检查或不安全的操作   注意:使用-Xlint重新编译:取消选中以获取详细信息。

如果使用-Xlint重新编译,它将告诉您不安全操作的位置以及导致它的原始类型:

>> javac -Xlint Test.java
Test.java:17: warning: [rawtypes] found raw type: Comparable
public static <T extends Comparable> T findMax2(List<T> list, int first, int second) {
                         ^
  missing type arguments for generic class Comparable<T>
  where T is a type-variable:
    T extends Object declared in interface Comparable

Test.java:20: warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type Comparable
        if (list.get(i).compareTo(max)>0) max = list.get(i);
                                 ^
  where T is a type-variable:
    T extends Object declared in interface Comparable
2 warnings

请求的受控示例:

public class Fake implements Comparable<Integer>{

    public int compareTo(Integer i){
        return i.compareTo(1);
    }

    public static <T extends Comparable> T findMax2(List<T> list, int first, int second) {
        T max = list.get(first);
        for (int i = first+1; i < second; i++) {
            if (list.get(i).compareTo(max)>0) max = list.get(i);
        }
        return max;
    }

    public static void main(String[] args){
        Fake fake = new Fake();
        List<Comparable<Integer>> l =  new ArrayList<>();
        l.add(fake);
        l.add(1);
        l.add(3);
        l.add(6);
        findMax2(l, 0, l.size()-1);
    }
}
  

线程“main”中的异常java.lang.ClassCastException:伪造不能转换为java.lang.Integer           在java.lang.Integer.compareTo(Integer.java:52)           在Fake.findMax2(Fake.java:12)           在Fake.main(Fake.java:24)

这个例子依赖于某人为一个完全不相关的类创建一个奇怪的Comparable类,但正如你所看到的,用你的符号表示,如果这个奇怪的类一起使用,就有可能得到异常。它可以比较的类。