最終這歸結爲一個事實,當你有這樣的事情:
class Me {
public static void go() {
System.out.println("going");
}
}
這些都將被允許:
Me.go();
Me meAgain = new Me();
meAgain.go(); // with a warning here
野趣的是,這將工作太例如:
Me meAgain = null;
meAgain.go();
就我個人而言,我仍然認爲這是設計缺陷,無法收回du e兼容性 - 但我希望編譯器不會允許我從實例訪問靜態方法。
你的第一個問題是不相關的Java-8每本身,它一直是這樣的java-8前:
interface ITest {
public void go();
}
class Test implements ITest {
public static void go() { // fails to compile
}
}
默認方法只是遵循相同的規則在這裏。爲什麼發生這種情況實際上在堆棧溢出中有相當多的細節 - 但潛在的想法是潛在的這會引起混淆調用哪種方法(想象ITest
將是Test
將會擴展的類,並且你做ITest test = new Test(); test.go()
;方法是,你哪位?)
我認爲,出於同樣的原因,這是不允許也(這基本上是你的第二個問題,否則你就必須使用相同的特徵碼的靜態和非靜態方法)
static class Me {
static void go() {
}
void go() {
}
}
有趣的是,這是一種固定的(我猜他們意識到它會成爲現實lly不好再做同樣的錯誤)在方法參考中:
static class Mapper {
static int increment(int x) {
return x + 1;
}
int decrement(int x) {
return x - 1;
}
}
Mapper m = new Mapper();
IntStream.of(1, 2, 3).map(m::increment); // will not compile
IntStream.of(1, 2, 3).map(m::decrement); // will compile
你正在使用哪種編譯器? – Hulk
這應該不依賴於默認實現或訪問級別的存在 - 在我看來,編譯錯誤應該是相同的。在eclipse中,它始終是「這個靜態方法不能從I中隱藏實例方法」,在[path]中使用oracle jdk 1.8.0_121「[path] /A.java:[5,17] m1()」.A不能實現m1()in [path] .I 重寫方法是靜態的 「 – Hulk
我正在使用1。8,它顯示不同的編譯錯誤 – user2185089