标题基本上说明了一切:如果我有一个在 T 中通用的 java 方法,我能找到关于 T 的任何信息吗?特别是,我可以检查 T 是否实现了某个接口或扩展了某个类?
我想做类似的事情
public <T> List<T> doSth(List<T> l) {
if(T extends Comparable) {
// do one thing
} else {
// do another
}
return l;
}
有什么提示吗?
非常感谢,
约翰内斯
标题基本上说明了一切:如果我有一个在 T 中通用的 java 方法,我能找到关于 T 的任何信息吗?特别是,我可以检查 T 是否实现了某个接口或扩展了某个类?
我想做类似的事情
public <T> List<T> doSth(List<T> l) {
if(T extends Comparable) {
// do one thing
} else {
// do another
}
return l;
}
有什么提示吗?
非常感谢,
约翰内斯
不清楚您是要在编译时还是在运行时执行检查。如果您只是想确保传递给方法的列表参数包含某些类型的对象,那么请T适当地重新定义。
例如,要确保编译器只允许将 aList<Comparable>传递给此方法,请重新定义T为:
public <T extends Comparable<? super T>> List<T> doSth(List<T> l) {
// Method body omitted
}
然后,您可以使用方法重载(而不是 if-else 语句)来确保为T. 换句话说,替换这个:
public <T> List<T> doSth(List<T> l) {
if(T extends Comparable) {
// do one thing
} else {
// do another
}
return null
}
用这些:
public <T extends Comparable<? super T>> List<T> doSth(List<T> l) {
// do one thing
return null;
}
public <T> List<T> doSth(List<T> l, Class<T> clazz) {
// do another
return null;
}
但是,您需要记住选择要调用的重载方法,并且泛型类型检查仅在编译时进行!例如,下面的代码:
List<? extends Serializable> alist = new ArrayList<Integer>();
doSth(alist);
实际上会调用第二种doSth方法,因为编译时类型参数 ( ? extends Serializable) 没有实现Comparable,即使运行时类型参数 ( Integer) 实现了。
否 - 由于类型擦除。在执行时,您根本不知道 T 的类型。
一种选择是将类型指定为另一个参数:
public <T> List<T> doSth(List<T> l, Class<T> clazz) {
if (Comparable.class.isAssignableFrom(clazz)) {
...
}
}
您应该在(甚至之前!:) 编译时就已经知道 T 是否扩展了 Comparable,那么为什么不创建两个方法呢?
public <T extends Comparable<T>> List<T> doSthComp(List<T> l) {
// do one thing
return l;
}
public <T> List<T> doSth(List<T> l) {
// do another
return l;
}
是的你可以:
public <T> List<T> doSth(List<T> l) {
//You could also check every element, if there is a chance only some will be comparable
if (l.size() >0 && l.get(0) instanceof Comparable) {
// do one thing
} else {
// do another
}
return l;
}
请注意,您正在检查“l”中的元素是什么类型,而不是 T - 这是关键。
编辑:更改了代码以处理它是一个列表的事实——我在原来的阅读中错过了这一点。
你可以做一个
public <T extends Comparable<T>> List<T> doSth(List<T> l)
这将允许您在项目中使用 Comparable 接口'l'
对于编译时检查,Don 已经给出了答案。对于运行时,只有当您还传递一个表示 T 的显式对象时才有可能,例如:
static <T> List<T> doSth(List<T> l, Class<T> tClass)
让 tClass 对象表示 T 的真实类,您可以检查它是否已通过反射实现可比较。但是从我的角度来看,编译时检查要好得多。