我无法掌握整个泛型声明,即使在阅读了关于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>{...}
会没问题吗?请给我揭开神秘面纱:(明天我会考试这个,如果不抓住这个,我就不能转移到其他东西...... :(
答案 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)
可以使用,但您无法在v1
或v2
上调用任何内容,因为T
只是一个没有约束的泛型类型,所以不会被允许。 v1.compareTo(v2)
导致编译错误。那么,你如何解决这个问题?
您对类型变量强制执行约束:
public <T extends Comparable<T>> void method(T v1, T v2)
通过这种方式,您将被强制传递给method()
只是必须实现Comparable<T>
的同一个类的实例,否则您将收到编译时错误。但是你的优势在于你可以调用compareTo(..)
,因为你可以保证传递给方法的对象能够响应它。
答案 1 :(得分:1)
按顺序:
X extends Y
和X super Y
用于表示“X
is-a Y
”和“Y
is-an {{1} }}“, 分别。 java开发人员不希望添加一个新的关键字,意思是“扩展或实现”。X
在这种情况下是泛型方法的类型声明,而不是泛型类。泛型类中的实例方法可以随意引用类的声明泛型类型,而无需重新声明它们;事实上,如果你重新声明它们,你将 shadowing 它们。< T extends Comparable< T > >
”是约束。您只能使用已知可自我比较的类型实例化您的类extends Comparable< T >
。因此Something
是合法的,但Something< Integer > si = new Something<>();
不合法,因为Something< Object > so = new Something<>();
未实现Object
。