微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 不兼容的类型和新鲜的类型变量

我得到以下编译消息:
[javac]   ... error: incompatible types
[javac]         exceptionClassHolder = new Holder<>( (new Exception()).getClass() );
[javac]                                ^
[javac]   required: Holder<Class<? extends Exception>>
[javac]   found:    Holder<Class<CAP#1>>
[javac]   where CAP#1 is a fresh type-variable:
[javac]     CAP#1 extends Exception from capture of ? extends Exception
[javac] 1 error

在我看来,根据消息一切都应该是正确的. CAP#1确实扩展了异常.那么上述消息应该如何理解呢? SSCCE下面(最初没有发布,因为我希望在一般情况下了解错误消息本身):

class Holder<T> {
    public T t;
    public Holder(T t) {
       this.t = t;
    }
}

public class FooMain {
    public static void main(String args[]) throws Exception {
        Holder<Class<? extends Exception>> exceptionClassHolder;
        exceptionClassHolder = new Holder<>( (new Exception()).getClass() );
    }
}

解决方法

不幸的是,现有的答案并不能解释这里发生了什么.首先,解决方案是简单地指定Holder的类型参数:
Holder<Class<? extends Exception>> exceptionClassHolder;
exceptionClassHolder =
        new Holder<Class<? extends Exception>>(new Exception().getClass());

你的版本不起作用的原因是因为新的Exception().getClass()返回一个Class<?扩展异常>,哪里?是一个wildcard capture(在编译器错误消息中称为CAP#1).由于您使用新的“持有者”的“钻石经营者”,所以编译器推断出类别< CAP#1扩展了Exception>对于T等等,持有者< Class< CAP#1扩展例外>>是创建对象的类型.

但是,这与您所声明的持有者类型 >.它使用一个 nested wildcard,它不捕获:而CAP#1扩展的异常是一些特定类型扩展异常,嵌套?扩展异常表示任何扩展异常的类型.

而< CAP#1扩展例外>是Class的子类型扩展异常>,持有者<类< CAP#1扩展异常>>不是Holder< Class<?扩展异常>>因为generics aren’t covariant,所以分配失败.

通过手动指定Class<?扩展异常>对于T,你可以帮助编译器避免这个“陷阱”.

看到我在这些帖子上的类似答案:

> Java: Wildcard Types Mismatch Results in Compilation Error
> Bounded-wildcard related compiler error

原文地址:https://www.jb51.cc/java/123308.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐