【问题标题】:Can I get Clazz.class on a generic type?我可以在泛型类型上获得 Clazz.class 吗?
【发布时间】:2014-04-01 09:48:31
【问题描述】:

我正在尝试在 List<MyType> 上调用 EasyMock.isA(Class<T>)。有没有办法在没有警告的情况下做到这一点?

我尝试了以下方法:

isA(List<MyType>.class);  // doesn't compile
isA(List.<MyType>class);  // syntax error on tokens (MyType), misplaced construct
isA(List.class);          // This gives a warning: Type safety: The expression of type List needs unchecked conversion to conform to List<MyType>

编辑

Jakub HR 给出了正确答案。但是,对于我需要 EasyMock 的特殊情况,我可以简单地使用

EasyMock.<List<MyType>>anyObject()

【问题讨论】:

  • 由于 JVM 中的类型参数擦除,您无法检查它(除非您使用自定义泛型 List 类,该类还存储在相应类型的实际 Class&lt;?&gt; 对象中(必须手动提供) ))

标签: java generics generic-list


【解决方案1】:

来自Effective Java

在新代码中不应该使用原始类型的规则有两个小例外,这两个例外都源于泛型类型信息在运行时被删除的事实。您必须在类文字中使用原始类型。该规范不允许使用参数化类型(尽管它确实允许数组类型和原始类型)。换句话说,List.classString[].class 和 int.class 都是合法的,但 List&lt;String&gt;.class and List&lt;?&gt;.class 不合法。

【讨论】:

    【解决方案2】:

    由于 JVM 中的类型参数擦除,您无法检查它(除非您使用自定义泛型 List 类,该类还存储在相应类型的实际 Class&lt;?&gt; 对象中(必须手动提供))
    这是因为在运行时无法知道泛型类型参数 — List&lt;String&gt;List&lt;MyType&gt; 等。在运行时都“被擦除”为 List&lt;Object&gt;(或者只是 List — 没有区别)。或许你也想看a more deep example out of the web

    【讨论】:

    • 你错了。 List 改为 List 而不是 List
    • @JakubHr 这是一样的。 List 只是一个“原始类型”,它在语言级别有所不同,但在字节码中没有。
    【解决方案3】:

    建议/接受的答案并不完全正确。这是一个更完整的答案:

    myMock.myMeth(isA(List.class)); // #1 fails if arg == null, warnings myMock.myMeth(EasyMock.&lt;List&lt;MT&gt;&gt; anyObject()); // #2 succeeds even when arg == null myMock.myMeth(anyObject()) // #3 same as #2

    myMock.myMeth(EasyMock.&lt;List&lt;MT&gt;&gt; notNull()); // #4 same as #1, no warnings! myMock.myMeth(notNull()); // #5 prob same as #1, less informative

    因此,如果您真的想要与 isA() 相同的行为,请使用 notNull() 而不是 anyObject()。请注意,当使用 anyObject() 或 notNull() 时,您实际上依赖于编译器来确保被调用的代码确实传递了正确的列表。如果你以某种方式设法将其他对象“伪造”到调用中(几乎不可能),EasyMock 不会用 anyObject() 或 notNull() 捕获它。

    【讨论】:

      【解决方案4】:

      你可以得到它:

      Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
      

      【讨论】:

      • 我在调用什么getClass()this?这似乎不对。
      • getClass() 如new ArrayList&lt;MyType&gt;() {}.getClass();。虽然从未尝试过一次,但理论上这应该可行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      相关资源
      最近更新 更多