泛型定义

时间:2013-11-07 23:39:47

标签: java generics declaration

我无法掌握整个泛型声明,即使在阅读了关于Java的书籍中的无数文章和条目之后,它们似乎都没有用简单明了的方式解释它。请有人能解释一下吗?:

class Something<T> {...}

我知道T是什么,并且我理解当我们想要为我们传入的任何类型的Object类型编写通用定义/方法时,我们使用泛型,而不是具有特定于一种类型的Object扩展的不同类型的方法,我们写一个通用的,可以包含一个或多个类型(因此大写T)。但最让我烦恼的是下一个宣言示例:

public <T extends Comparable<T>> void Something{...}

首先关闭;可比较的是一个接口而不是一个类(如果我错了,请纠正我)所以第一个原因是extends而不是implements。现在,为什么必须在void和现在Comparable<T>之前声明它(整个&lt; T ...&gt;事物)?那是什么意思?进入的Object类型必须有implements Comparable<T>?因此,如果我想传递类型参数class Something{...}我会收到错误,但是传递class Something implements Comparable<T>{...}会没问题吗?请给我揭开神秘面纱:(明天我会考试这个,如果不抓住这个,我就不能转移到其他东西...... :(

2 个答案:

答案 0 :(得分:6)

首先在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)

可以使用,但您无法在v1v2上调用任何内容,因为T只是一个没有约束的泛型类型,所以不会被允许。 v1.compareTo(v2)导致编译错误。那么,你如何解决这个问题?

您对类型变量强制执行约束:

public <T extends Comparable<T>> void method(T v1, T v2)

通过这种方式,您将被强制传递给method()只是必须实现Comparable<T>的同一个类的实例,否则您将收到编译时错误。但是你的优势在于你可以调用compareTo(..),因为你可以保证传递给方法的对象能够响应它。

答案 1 :(得分:1)

按顺序:

    泛型类型声明中的
  1. X extends YX super Y用于表示“X is-a Y”和“Y is-an {{1} }}“, 分别。 java开发人员不希望添加一个新的关键字,意思是“扩展或实现”。
  2. 声明在返回类型之前,可能是因为一旦声明了泛型类型变量,返回类型可能会使用其中的一些。顺便提一下,正如@Jack指出的那样,X在这种情况下是泛型方法的类型声明,而不是泛型。泛型类中的实例方法可以随意引用类的声明泛型类型,而无需重新声明它们;事实上,如果你重新声明它们,你将 shadowing 它们。
  3. < T extends Comparable< T > >”是约束。您只能使用已知可自我比较的类型实例化您的类extends Comparable< T >。因此Something是合法的,但Something< Integer > si = new Something<>();不合法,因为Something< Object > so = new Something<>();未实现Object