考虑以下代码示例:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List list = new ArrayList<Integer>();
        String response = getProducer(list).get();
    }
    static Producer<String> getProducer(List<Integer> list) {
        return new Producer<String>();
    }
}
class Producer<T> {
    T get() {
        return null;
    }
}

用Java 7编译时,它只会对getProducer(list)产生预期的警告:



但是,当使用Java 8进行编译时,会为response = getProducer(list).get()分配产生以下错误:



因此,显然从getProducer(list)返回的类型不是Producer<String>,而是擦除的Producer(也可以通过IDE中的“提取变量”功能确认)。这非常令人困惑,因为getProducer方法始终返回Producer<String>

奇怪的是,可以通过在调用getProducer方法时避免未经检查的转换来解决此问题,方法是:
  • getProducer的参数类型从List<Integer>更改为List
  • list变量的类型从List更改为List<Integer>

  • 更新
  • 使用的Java是Oracle JDK 1.8.0_40
  • 我也尝试过使用Java 8编译器从1.5到1.7使用source和target选项,结果是相同的。

  • 问题
  • 传递的参数的通用类型如何影响方法返回值的通用类型,而返回值的通用类型在方法签名中是固定的?
  • 为什么Java 7和Java 8之间的行为向后不兼容?
  • 最佳答案

    这看起来像一个已知的兼容性问题herehere

    从第二个链接:


    import java.util.List;
    class SampleClass {
    
         static class Baz<T> {
             public static List<Baz<Object>> sampleMethod(Baz<Object> param) {
                 return null;
             }
         }
    
         private static void bar(Baz arg) {
             Baz element = Baz.sampleMethod(arg).get(0);
         }
    }
    



    因此,可以通过替换此行来固定OP的代码(右侧的类型声明使我失望-我将其视为不是类型化数组列表的形式阅读):
    List list = new ArrayList<Integer>();
    


    List<Integer> list = new ArrayList<Integer>();
    

    这不会导致从方法getProducer(List<Integer> list)的返回类型中删除类型

    再次引用第二个链接:

    10-01 02:57
    查看更多