我无法理解整个泛型声明,即使在阅读了无数关于 Java 的文章和书籍条目之后,似乎没有一篇能以简单明了的方式解释它。谁能给我解释一下吗?:
class Something<T> {...}
我知道 T 是什么,我知道当我们想为我们传入的任何类型的对象编写通用定义/方法时,我们会使用泛型,而不是针对一种类型的对象扩展使用不同类型的方法,我们写了一个通用的,它可以包含一种或多种类型(因此是大写的 T)。但最让我烦恼的一件事是下一个声明示例:
public <T extends Comparable<T>> void Something{...}
首先; Comparable 是一个接口(interface)而不是一个类(如果我错了请纠正我)所以第一个为什么是它 extends
而不是 implements
.现在,为什么必须在 void
之前声明它(整个 < T ...> 事情)现在 Comparable<T>
??这意味着什么?进入的对象类型必须有 implements Comparable<T>
?因此,如果我想将类 class Something{...}
作为类型参数 传递我会得到一个错误,但传递 class Something implements Comparable<T>{...}
会好吗?请给我揭开这个神秘面纱:(我明天要考试,如果不掌握这个我就不能转移到其他事情上......:(
最佳答案
首先在 Java 中你有两件事:
- 通用类型,如
class GenericContainer<T>
- 像你的例子一样的通用方法
public <T> method()
前者用于定义泛型类,后者用于定义泛型方法。这是两个不同的事物,尽管它们都使用相同的原理。
你必须明确声明一个方法是通用的,就像在
public <T extends Comparable<T>> void myGenericMethod(...)
只是您在 Java 中声明泛型方法的方式。这只是语法。如果要声明泛型方法,则必须在方法签名之前使用该语法指定类型参数。
关于您关于 T extends Comparable<T>
的问题想想这个事实:当使用通用变量时,比如 T myVariable
,您将不得不出于某种目的使用此变量。由于 Java 是一种强类型语言,您将能够了解关于 T
的一切必须在编译类型上决定。
在您的示例中,假设您希望现在能够对两个对象进行排序
public <T> void method(T v1, T v2)
会工作,但你不能在 v1
上调用任何东西或 v2
, 你不会被允许因为 T
只是一个没有约束的通用类型。 v1.compareTo(v2)
导致编译错误。那么,如何解决这个问题?
你对类型变量强制约束:
public <T extends Comparable<T>> void method(T v1, T v2)
这样你会被强制传递给method()
只是必须实现 Comparable<T>
的同一类的实例否则你会得到一个编译时错误。但是您将拥有一个优势,即您可以调用 compareTo(..)
因为您可以保证传递给该方法的对象能够响应它。
关于java - 泛型定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19848961/