首页 > 解决方案 > 如何使用 java 泛型类型参数?

问题描述

有什么区别

public static <T> double sums(Collection<T extends Number> numbers) {} 

和这个

public static <T extends Number> double sums(Collection<T> numbers) {}

和这个

public static double sums(Collection<? extends Number> numbers) {}

和这个

public static <T> double sums(Collection<? extends Number> numbers) {}

<T>我知道如果我们只对一种方法使用泛型,我们会在返回类型之前提到类型参数。我们可以在这里使用类型参数 T,因为它被声明为类类型参数( public class generics<T extends Integer >{})。我不太明白它们之间的区别。尤其是第一个和最后一个。我在第一条语句上得到编译错误,在最后一条语句上没有错误。为什么我需要?在第一个语句中使用通配符?我可以知道静态关键字如何影响此方法声明吗?

编辑:我没有使用方法内部的类型,所以类型参数<T><?>功能应该相同。我只使用了一个参数化类型参数,根据这篇文章,即使我们在那里使用通配符,它​​也应该是相同的,但是当我使用类型参数时我得到了编译错误。

标签: javagenerics

解决方案


让我们分解它们。

  1. 这是无稽之谈。不要这样做。它不会编译是有原因的。

  2. 在这里,我们定义了一个通用函数sums。我们的函数可以使用包含某些特定数值类型元素的集合来调用。

  3. 这类似于(2)。更多关于下面的内容。

  4. 这是(3)的一个奇怪版本。也不要这样做;你刚刚声明了一个类型参数并没有使用它,所以真的没有意义。

现在,(2)和(3)非常相似。当我们?用作类型参数时,我们本质上是在说“这可以是任何东西,但我并不特别关心它的值是什么”。另一方面,当我们显式使用 时T,我们可以使用该类型参数来做其他事情。这是一个类型级别的变量。

public static <T extends Number> double sums(Collection<T> numbers) {
  for (T arg : numbers) {
    // Do something with arg
  }
}

我们可以对结构进行迭代,并且我们的结构arg很好,因为我们知道集合中有什么类型的东西。对于(3),我们丢失了一些信息。

public static double sums(Collection<? extends Number> numbers) {
  for (Number arg : numbers) {
    // Do something with arg
  }
}

我们知道numbers包含一些特定类型的数字,但我们不知道它是什么,所以我们不得不退回到更一般但仍然安全的数字Number


推荐阅读