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 个错误
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论