![](/img/trans.png)
[英]Java code not compiling with 'javac' but compiles in Eclipse
[英]Java CRTP and Wildcards: Code compiles in Eclipse but not `javac`
對不起,標題含糊不清。 我有這段代碼編譯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
上進行javac
,而不更改v
方法的簽名(即保留通配符)?
我知道將它更改為<T extends N<T>> void v(final R<T> r)
確實使它編譯,但我想知道是否有辦法首先避免這種情況。 此外,方法p
不能改變為<T extends N<?>> void p(final T n)
因為內容具有需要精確約束T extends N<T>
。
通配符的局限性在於它們會破壞類型參數允許的T extends X<T>
類的遞歸表達式。 根據以下內容,我們知道您要做的是安全的:
ro
是T
型(由R
聲明),它是或延伸N<T>
。 p
采用類型為T
的參數(由p
聲明),它也是或者擴展N<T>
。 r
被輸入為R<?>
,理論上呼叫p(ro)
應該是合法的。 這可能是eclipse編譯器的推理(已知對javac沒有的泛型的某些細微差別做出正確的限制)。
假設您想使用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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.