标题基本上都说明了:如果我有一个在T中是通用的java方法,我可以找到关于T的任何内容吗?特别是,我可以检查T是实现某个接口还是扩展某个类?
我想做点什么
public <T> List<T> doSth(List<T> l) {
if(T extends Comparable) {
// do one thing
} else {
// do another
}
return l;
}
任何提示?
非常感谢,
约翰
答案 0 :(得分:10)
目前尚不清楚是否要在编译时或运行时执行检查。如果您只是想确保传递给方法的list参数包含某些类型的对象,请相应地重新定义T
。
例如,要确保编译器仅允许将List<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
确实。
答案 1 :(得分:4)
不 - 由于type erasure。在执行时,您根本不知道T的类型。
一种选择是将类型指定为另一个参数:
public <T> List<T> doSth(List<T> l, Class<T> clazz) {
if (Comparable.class.isAssignableFrom(clazz)) {
...
}
}
答案 2 :(得分:1)
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 - 这是关键。
编辑:更改了代码以处理它是一个列表的事实 - 我在原始阅读中错过了它。
答案 3 :(得分:1)
你应该已经知道(甚至之前!:)编译时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;
}
答案 4 :(得分:0)
你可以做一个
public <T extends Comparable<T>> List<T> doSth(List<T> l)
允许您对'l'
答案 5 :(得分:0)
好的编译时间检查唐已经给出了答案。对于运行时,只有在您还传递表示T的显式对象时才有可能,例如:
static <T> List<T> doSth(List<T> l, Class<T> tClass)
如果tClass对象代表T的真实类,你可以检查它是否已通过反射实现了可比性。但是从我的角度来看,编译时检查要好得多。