我从教程中找到了这段代码,我猜这种方法getUriBase
返回类型是String
,但不清楚<T extends IEntity>
在这种方法中扮演什么部分以及为什么它放在开头?
public interface IUriMapper {
<T extends IEntity> String getUriBase(final Class<T> clazz);
}
这是创建泛型方法的约定。
泛型方法的语法包括一个类型参数,里面 尖括号,并显示在方法的返回类型之前。为 静态泛型方法,类型参数部分必须出现在 方法的返回类型。
如果你看到 那么在返回类型之前String
定义你的类型参数T
.现在,来到<T extends IEntity>
,基本上你正在创建一个有界类型参数,其中你告诉编译器T
应该只是IEntity
的子类。
需要注意的重要一点是,您需要在方法之前定义<T extends IEntity>
(这就是您所说的"泛型方法",更多信息即将到来......),因为您的接口不是泛型类型,假设您的接口如下所示,那么您不需要定义T
类型参数,因为编译器会知道什么是T
类型参数。
public interface IUriMapper<T extends IEntity> {
String getUriBase(final Class<T> clazz);
}
因此,当您想要定义自己的类型时,基本上泛型方法很有用(或者换句话说,适用于各种情况)。考虑以下示例,其中泛型类型(接口"IUriMapper")定义了类型参数"T",但对于方法getUriBase
,您正在创建一个新类型"E">
public interface IUriMapper<T extends IEntity> {
<E extends Number> String getUriBase(final Class<E> clazz);
}
此 Oracle 文档是学习泛型的最佳来源。
型类型
类型参数部分由尖括号 (<>) 分隔,跟在类名之后。它指定类型参数(也称为类型变量)T1、T2、...和Tn。
public class Box {
private Object object;
public void set(Object object) { this.object = object; }
public Object get() { return object; }
}
若要更新 Box 类以使用泛型,可以通过将代码"public class Box"更改为"public class Box"来创建泛型类型声明。这引入了类型变量 T,该变量可以在类中的任何位置使用。
/**
* Generic version of the Box class.
* @param <T> the type of the value being boxed
*/
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
来源:https://docs.oracle.com/javase/tutorial/java/generics/types.html
有界类型参数:
有时可能需要限制可在参数化类型中用作类型参数的类型。例如,对数字进行操作的方法可能只想接受 Number 或其子类的实例。这就是有界类型参数的用途。
public class Box<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
public <U extends Number> void inspect(U u){
System.out.println("T: " + t.getClass().getName());
System.out.println("U: " + u.getClass().getName());
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>();
integerBox.set(new Integer(10));
integerBox.inspect("some text"); // error: this is still String!
}
}
来源: https://docs.oracle.com/javase/tutorial/java/generics/bounded.html