Java CRTP和通配符:代码在Eclipse中编译,但不是`javac`
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java CRTP和通配符:代码在Eclipse中编译,但不是`javac`,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1638字,纯文字阅读大概需要3分钟。
内容图文
![Java CRTP和通配符:代码在Eclipse中编译,但不是`javac`](/upload/InfoBanner/zyjiaocheng/826/d96fb79e26f54e1da9cf11fb376c1f7f.jpg)
对不起,标题含糊不清.我有这段代码编译Eclipse Juno(4.2)但不是javac(1.7.0_09):
package test;
public final class Test {
public static class N<T extends N<T>> {}
public static class R<T extends N<T>> {
public T o;
}
public <T extends N<T>> void p(final T n) {}
public void v(final R<?> r) {
p(r.o); // <-- javac fails on this line
}
}
错误是:
Test.java:13: error: method p in class Test cannot be applied to given types; p(r.o); ^ required: T found: N<CAP#1> reason: inferred type does not conform to declared bound(s) inferred: N<CAP#1> bound(s): N<N<CAP#1>> where T is a type-variable: T extends N<T> declared in method <T>p(T) where CAP#1 is a fresh type-variable: CAP#1 extends N<CAP#1> from capture of ? 1 error
所以问题是:
>这是一个javac bug还是Eclipse bug?
>有没有办法在javac上进行编译,而不更改v方法的签名(即保留通配符)?
我知道将其改为< T extends N< T>> void v(最终R< T> r)确实使它编译,但我想知道是否有办法首先避免这种情况.而且,方法p不能改变为< T extends N>>. void p(final T n)因为内容具有需要精确约束的类型T延伸N T.
解决方法:
通配符是有限的,因为它们破坏递归表达式,如T extends X< T>.那种类型参数允许.根据以下内容,我们知道您要做的是安全的:
> r.o是T型(由R声明),其是或延伸N T.
>方法p采用类型为T的参数(由p声明),该参数也是或者扩展为N< T>.
>因此即使r被输入为R<?>,理论上呼叫p(r.o)应该是合法的.
这可能是eclipse编译器的推理(已知可以为javac doesn’t的某些细微差别做出正确的限制).
假设您想使用javac进行编译并且不能像您提到的那样更改v的签名,那么您可以做的最好的事情就是使用原始类型,它“选择”泛型类型检查:
public void v(final R<?> r) {
//necessary to placate javac - this is okay because [insert above reasoning]
@SuppressWarnings("rawtypes")
N nRaw = r.o;
p(nRaw);
}
内容总结
以上是互联网集市为您收集整理的Java CRTP和通配符:代码在Eclipse中编译,但不是`javac`全部内容,希望文章能够帮你解决Java CRTP和通配符:代码在Eclipse中编译,但不是`javac`所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。