在泛型方法<t> doSth(List <t> l)中,检查T是否实现了Comparable?</t> </t>

时间:2009-10-13 16:48:49

标签: java generics instanceof

标题基本上都说明了:如果我有一个在T中是通用的java方法,我可以找到关于T的任何内容吗?特别是,我可以检查T是实现某个接口还是扩展某个类?

我想做点什么

public <T> List<T> doSth(List<T> l) {

  if(T extends Comparable) {
    // do one thing
  } else {
    // do another
  }

  return l;
}

任何提示?

非常感谢,

约翰

6 个答案:

答案 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'

中的项目使用Comparable接口

答案 5 :(得分:0)

好的编译时间检查唐已经给出了答案。对于运行时,只有在您还传递表示T的显式对象时才有可能,例如:
static <T> List<T> doSth(List<T> l, Class<T> tClass) 如果tClass对象代表T的真实类,你可以检查它是否已通过反射实现了可比性。但是从我的角度来看,编译时检查要好得多。