【问题标题】:Unchecked cast abstract base class未经检查的强制转换抽象基类
【发布时间】:2017-03-30 09:49:03
【问题描述】:

谁能解释一下,为什么这个演员没有被选中。应保证T 类型始终派生自Base,因此不应取消选中从TBase 的转换。

abstract class Base
{
    private static final Map<Class<? extends Base>, Consumer<Base>> _CONSUMERS = new HashMap<>();

    @SuppressWarnings( "unchecked" )
    public static <T extends Base> void addConsumer( Class<T> clazz, Consumer<T> consumer )
    {
        _CONSUMERS.put( clazz, (Consumer<Base>) consumer );
    }
}

【问题讨论】:

    标签: java casting abstract-class


    【解决方案1】:

    consumer 的类型是 Consumer&lt;T&gt; = Consumer&lt;? extends Base&gt;,而 put 需要 Consumer&lt;Base&gt;

    您可能应该将您的 _CONSUMERS 映射声明为类型:

    Map<Class<? extends Base>, Consumer<? extends Base>>
    

    Java 无法识别可以使用 X&lt;? extends T&gt;(或 X&lt;? super T&gt;)类型的对象代替 X&lt;T&gt; 的情况,您必须明确指出类型边界(参见 here 对此进行更深入的讨论) .

    【讨论】:

    • 我采纳了你的答案,现在 put 没有更多警告了,但是当我想给消费者打电话时,我必须做一个未经检查的演员 Consumer&lt;Base&gt; consumer = (Consumer&lt;Base&gt;) _CONSUMERS.get( Concrete.class );。否则我不能打电话给accept
    • 我忘了...如果您正在处理java.util.function.Consumer(或概念上类似的东西),我认为您应该使用&lt;? super Base&gt; 代替&lt;? extends Base&gt;:这应该让您检索 Consumer&lt;? super Base&gt; 并使用 Base 类型的参数调用其 accept 方法,无需任何转换
    • 感谢您的建议,但我无法通过 super 解决问题,并且没有抑制警告。
    猜你喜欢
    • 1970-01-01
    • 2012-10-13
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多