【问题标题】:Generics - Legal alternative for (elements instanceof List<? extends Comparable>)泛型 - (elements instanceof List<? extends Comparable>) 的合法替代方案
【发布时间】:2011-08-07 19:04:04
【问题描述】:

我有这个方法,它的唯一参数 (List elements) 将元素设置为 ListModel,但我需要进行验证以查看泛型类型是否实现了可比性,因为这样的事情:

if (elements instanceof List<? extends Comparable>)

是非法的,我不知道如何进行正确的验证。

更新

我已经使用以下方法完成了此验证:

(elements.size() > 0 && elements.get(0) instanceof Comparable)

但我想知道是否有更清洁的解决方案,例如使用反射?

提前致谢。

【问题讨论】:

  • 看起来你并不真正知道你到底想要什么。 Comparable 本身毫无用处 - 这就是为什么它现在被参数化为 Comparable - 因为您需要知道它能够与什么进行比较。即使您能够获得这个 List of Comparable 实例,如果它们不能相互比较(例如,该列表包含一个 String 和一个 BigDecimal 类型),您将仍然在运行时,这是泛型试图通过编译器错误来防止的。

标签: java generics syntax instanceof


【解决方案1】:

列表的通用类型是erased at runtime。为此,您需要在方法签名中要求参数或单独测试每个元素。

public void doSomething(List<? extends Comparable> elements) {}

for (Object o : elements) {
    if (o instanceof Comparable) {}
}

如果您可以控制代码,则首选且更简洁;如果需要,可以将后者包装在实用方法调用中。

【讨论】:

  • 参数必须是 List,不能是泛型,List&lt;?&gt;,因为它是一个 ListModel,可以接受其元素可能无法实现 Comparable 的列表。这只是一个验证,看看我是否对元素进行了排序。我正在尝试使用反射,但是当我使用 ((ParameterizedType) elements.getClass().getGenericSuperclass()) 时,我没有得到我想要的。
【解决方案2】:

这是不可能的。 instanceof 是运行时运算符,而通用信息在运行时会丢失(类型擦除)。

【讨论】:

  • 是的,你是对的,不记得类型擦除!但我需要让这件事发生! (验证元素是否实现Comparable,不做if (elements.size() &gt; 0 &amp;&amp; elements.get(0) instanceof Comparable),我觉得太丑了。呵呵。
【解决方案3】:

我不是泛型专家,但据我了解,您不能这样做的原因是在运行时,ArrayListArrayList&lt;String&gt; 之间没有区别。因此,执行您想要的测试为时已晚。

为什么不直接声明你的方法接受List&lt;? extends Comparable&gt; 而不是List

特别是,您提出问题的方式听起来像是您希望列表总是包含同质元素,但是普通的旧 List 并不能给您任何保证,例如那个。

【讨论】:

  • 我不能让方法接受List&lt;? extends Comparable&gt;,因为它可以接受任何列表,甚至是集合,我只需要检查元素是否实现了 Comparable 来进行排序。我已经有if (elements.size() &gt; 0 &amp;&amp; elements.get(0) instanceof Comparable),但正如我之前所说,我认为它太丑陋了。试图通过反射了解这是否可能。
  • 但是等一下。如果有些元素支持 Comparable 而有些不支持呢?此外,例如,如果一个元素是String 而另一个元素是Long,该怎么办?它们都实现了Comparable,但你无法比较它们。
【解决方案4】:

对于您的更新:仅确保一个元素实现 Comparable 是不够的(如果其他元素不实现呢?)并且确保所有元素都实现 Comparable 也不足以验证(如果它们是实现 Comparable 但不能相互比较的不同类?)。

但更大的问题是,为什么还要在运行时验证呢?与简单地尝试使用它然后看到它失败(即抛出异常,也许你可以捕获)相比,这有什么好处?

【讨论】:

    猜你喜欢
    • 2022-12-17
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多