1

我无法理解整个泛型声明,即使在阅读了无数关于 Java 的文章和条目之后,似乎也没有一个能够以简单明了的方式解释它。请问谁能给我解释一下?:

class Something<T> {...}

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

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

首先;Comparable 是一个接口而不是一个类(如果我错了,请纠正我)所以第一个为什么是它extends而不是implements. 现在,为什么必须在之前void和现在声明(整个 <T ...> 事情) Comparable<T>?这意味着什么?进入的对象类型必须有implements Comparable<T>?因此,如果我想将类作为类型参数class Something{...}传递,我会得到一个错误,但传递class Something implements Comparable<T>{...}就可以了吗?请向我揭开这个神秘的面纱:(我明天有一个考试,如果不掌握这个我就不能转移到其他事情...... :(

4

2 回答 2

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)

会工作,但你不能在v1or上调用任何东西v2,你不会被允许,因为T它只是一个没有约束的泛型类型。v1.compareTo(v2)导致编译错误。那么,你如何解决这个问题呢?

您对类型变量实施约束:

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

这样,您将被迫method()仅传递给必须实现的同一类的实例,Comparable<T>否则您将收到编译时错误。但是您将获得允许调用的优势,compareTo(..)因为您可以保证传递给该方法的对象将能够响应它。

于 2013-11-07T23:48:15.333 回答
1

为了:

  1. X extends YX super Y在泛型类型声明中,分别用于表示“ Xis-a Y”和“ Yis-an X”。Java 开发人员不希望添加一个新的关键字,意思是“扩展或实现”。
  2. 声明在返回类型之前,大概是因为一旦您声明了泛型类型变量,返回类型可能会使用其中的一些。顺便说一句,正如@Jack 指出的那样,< T extends Comparable< T > >在这种情况下是泛型方法的类型声明,而不是泛型。泛型类中的实例方法可以随意引用该类声明的泛型类型,而无需重新声明它们;实际上,如果您确实重新声明它们,您将影响它们。
  3. " extends Comparable< T >" 是一个约束。您只能Something使用已知可自比的类型来实例化您的类。所以Something< Integer > si = new Something<>();是合法的,但Something< Object > so = new Something<>();不是,因为Object不实施Comparable< Object >
于 2013-11-07T23:47:12.603 回答