java-se - java无界通配符作为超类型通配符参数和子类型通配符参数使用?
伊谢尔伦
伊谢尔伦 2017-04-17 16:50:15
[Java讨论组]

我在看《thingking in java》中泛型的无界统配符时的例子时,对于使用无界通配符参数作为? super? extends的参数时的编译结果很不理解.

class Holder<T>
{
    void set(T t){}
    T get(){return null;}
}
class Main
{
    static <T> T exact3(Holder<? extends T> holder , T t)
    {
        return holder.get() ;
    }

    static <T> T exact4(Holder<? super T> holder , T t)
    {
        holder.set(t) ;

        return null ;
    }
    
    
    public static void main(String args[])
    {
        Holder<?> holder = new Holder<Long>() ;
        Long lng = 22L ;
        exact3(holder , lng) ;    //可以编译执行且不产生警告
        exact4(holder , lng) ;    //编译失败
    }
}

我自己的解释是:

exact4<?>不能作为<? super T>的参数, 是因为<?>不等价于<? super T>, 所以编译失败; 而exact3<?>却可以作为<? extends T>的参数, 是因为使用<? extends T>只能从这个Holder取出T类型的对象,而不能放入其他对象,不会对这个Holder的安全产生影响, 所以编译器允许了这种行为.
但是感觉这种解释很牵强, 那么该怎么理解无界通配符面对这两种情况的不同呢?

    ---------- javac ----------
    错误: 无法将类 Main中的方法 exact4应用到给定类型;
            exact4(holder , lng) ;    //编译失败
            ^
      需要: Holder<? super T>,T
      找到: Holder<CAP#1>,Long
      原因: 无法推断类型变量 T
        (参数不匹配; Holder<CAP#1>无法转换为Holder<? super T>)
      其中, T是类型变量:
        T扩展已在方法 <T>exact4(Holder<? super T>,T)中声明的Object
      其中, CAP#1是新类型变量:
        CAP#1从?的捕获扩展Object
    1 个错误
伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

全部回复(0)
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号