在通用方法中doSth(Listl),检查T是否实现了Comparable?

发布于 2024-08-08 05:33:01 字数 325 浏览 1 评论 0原文

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

我想做一些类似的事情

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

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

  return l;
}

有提示吗?

非常感谢,

约翰内斯

The title basically says it all: if I have a java method that is generic in T, can I find out anything about T? In particular, can I check whether T implements a certain interface or extends a certain class?

I would like to do something like

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

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

  return l;
}

Any hints?

Thanks a lot,

Johannes

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一江春梦 2024-08-15 05:33:01

目前尚不清楚是否要在编译时或运行时执行检查。如果您只是想确保传递给方法的列表参数包含某些类型的对象,则适当地重新定义 T

例如,为了确保编译器只允许将 List 传递给此方法,请将 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 Serialized)没有实现Comparable code>,即使运行时类型参数 (Integer) 也是如此。

It's not clear whether you want to perform the check at compile-time or at runtime. If you simply want to ensure that the list parameter passed to the method contains certain types of objects, then redefine T appropriately.

For example, to ensure that the compiler will only allow a List<Comparable> to be passed to this method, redefine T as:

public <T extends Comparable<? super T>> List<T> doSth(List<T> l) {
    // Method body omitted
}

You can then use method-overloading (instead of an if-else statement), to ensure the correct code is called for any value of T. In other words, replace this:

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

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

    return null
}

with these:

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;
}

However, you need to remember choosing which overloaded method to call and generic-type checking is compile-time only! For example, the following code:

List<? extends Serializable> alist = new ArrayList<Integer>();
doSth(alist);

will actually call the second doSth method, because the compile-time type parameter (? extends Serializable) does not implement Comparable, even though the runtime type parameter (Integer) does.

清醇 2024-08-15 05:33:01

否 - 由于类型擦除。在执行时,您根本不知道 T 的类型。

一种选择是将类型指定为另一个参数:

public <T> List<T> doSth(List<T> l, Class<T> clazz) {
    if (Comparable.class.isAssignableFrom(clazz)) {
        ...
    }
}

No - due to type erasure. At execution time, you don't know the type of T at all.

One option would be to specify the type as another parameter:

public <T> List<T> doSth(List<T> l, Class<T> clazz) {
    if (Comparable.class.isAssignableFrom(clazz)) {
        ...
    }
}
浅忆流年 2024-08-15 05:33:01

是的,您可以:

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 - 这是关键。

编辑:更改了代码以处理它是一个列表的事实 - 我在原来的阅读中错过了这一点。

yes, you can:

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;
}

Note that you are checking what type the elements in "l" are, NOT T - that is the key.

Edit: Changed the code to handle the fact that it was a list - I had missed that in my original reading.

蓝眼睛不忧郁 2024-08-15 05:33:01

您应该在编译时(甚至在之前!:)知道 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;
}

You should already know at (even before! :) compile time whether T extends Comparable or not, so why not make two methods?

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;
}
童话里做英雄 2024-08-15 05:33:01

您可以执行以下操作

public <T extends Comparable<T>> List<T> doSth(List<T> l)

,这将允许您在 'l' 中的项目上使用 Comparable 接口

You can do a

public <T extends Comparable<T>> List<T> doSth(List<T> l)

which will allow you to use the Comparable interface on items in 'l'

薄荷→糖丶微凉 2024-08-15 05:33:01

好吧,对于编译时间检查,Don 已经给出了答案。对于运行时,只有当您还传递一个表示 T 的显式对象时才有可能,例如:
<代码>
静态列表doSth(Listl, ClasstClass)
拥有代表 T 的真实类的 tClass 对象,您可以检查它是否通过反射实现了可比性。但从我的角度来看,编译时检查要好得多。

Well for compile time check Don already gave an answer. For the runtime it's only possible if you also pass a explicit object representing T, for example:

static <T> List<T> doSth(List<T> l, Class<T> tClass)

having tClass object representing real class of T you can check if it have implemented comparable via reflection. But compile-time check is much, much better from my point of view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文