【问题标题】:What's the difference between Java 8 and Java 7 related to generic methods in type parameter bound?Java 8 和 Java 7 与类型参数绑定中的泛型方法有什么区别?
【发布时间】:2020-05-06 08:41:16
【问题描述】:
public class GenMethodDemo2 {
    static <T, V extends T> boolean isIn(T x, V[] y){
        for (int i = 0; i < y.length; i++) {
            if (x.equals(y[i])) return true;
        }
        return false;
    }

    @Test
    public void test(){
        Integer[] nums = {1,2,3,4,5};
        if(isIn("java",nums)) System.out.println("java is in nums");
        if(!isIn("java",nums)) System.out.println("java is not in nums");
    }
}

当我使用 jdk8 时,这段代码运行良好,结果是 java is not in nums

但是当我更改为 jdk7 时,相同的代码将无法编译,并且提示 msg 为Inferred type 'java.lang.Integer' for type parameter 'V' is not within its bound; should extend 'java.lang.String'

我想知道:当函数显式定义类型参数绑定V extends T时,jdk8如何编译这段代码?

【问题讨论】:

  • 在jdk7上怎么运行不好?
  • @Thilo 抱歉,strArray 在 test(){ String[] strArray = {"hello","java","is","well"}; }
  • 你在 Java 7 上遇到了什么问题?
  • 不同的JDK版本导入哪个版本的库会不会有区别?
  • @ernest_k 很抱歉提出问题忘记添加明确的错误消息,我更改了它希望澄清错误

标签: java generics java-8 java-7


【解决方案1】:

我相信与 Java 7 相比,Java 8 中的泛型方法的类型推断有一些改进,但我不确定它是否能解释您所看到的差异。在任何情况下,当推理失败时,您始终可以显式提供类型见证,以向编译器证明存在将满足边界的类型,例如:

if (GenMethodDemo2.<Object, Integer>isIn("java",nums))
    System.out.println("java is in nums");

在这种情况下,类型变量TV 始终可以选择为Object,并且它不会接受更少的参数集(因为任何T 都将是@ 的子类型987654326@ 和任何V[] 都将是Object[] 的子类型。所以你的方法实际上不需要任何泛型:

static boolean isIn(Object x, Object[] y){
    for (int i = 0; i < y.length; i++) {
        if (x.equals(y[i])) return true;
    }
    return false;
}

【讨论】:

  • 感谢您的帮助,有了您的回答,我意识到 java8 更聪明
【解决方案2】:

类似的签名

static <T, V extends T> boolean isIn(T x, V[] y)

并不比

好多少
static boolean isIn(Object x, Object[] y)

因为调用者总是可以将Object 用于T,它允许任意对象作为第一个参数,以及数组元素的任意引用类型。

因此,当您将方法更改为

@Test
public void test(){
    Integer[] nums = {1,2,3,4,5};
    if(GenMethodDemo2.<Object,Integer>isIn("java",nums))
            System.out.println("java is in nums");
    if(!GenMethodDemo2.<Object,Integer>isIn("java",nums))
            System.out.println("java is not in nums");
}

它可以在所有支持泛型的 Java 版本中编译。

由于协变数组,它也可以指定

if(GenMethodDemo2.<Object,Object>isIn("java",nums))
        System.out.println("java is in nums");
if(!GenMethodDemo2.<Object,Object>isIn("java",nums))
        System.out.println("java is not in nums");

Java 8 的类型推断不会改变哪个方法调用是有效的,它只会使执行有效调用变得更容易,因为您需要显式指定类型参数的场景更少。

【讨论】:

  • 感谢您的帮助,当我浏览您的答案时,看起来java8更人性化的设计
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多