2017-04-06 62 views
3

考慮下面的代碼:爲什麼你可以導入一個與嵌套類名稱相同的類?

import java.util.Calendar; 

class Demo 
{ 
    class Calendar {} 

    public static void main (String[] args) { 
     // System.out.println(Calendar.DAY_OF_WEEK); // Would be an error. 
    } 
} 

此代碼編譯的罰款;但如果你是指CalendarDemo,你是指Demo.Calendar,不java.util.Calendar

導入顯然是多餘的;但似乎奇怪的是,它是允許的,考慮到你不能用相同的簡單名稱導入一個類,如在同一編譯單元中定義(每JLS Sec 7.5.1)一個頂級類:

import java.util.Calendar; // error: Calendar is already defined in this compilation unit 

class Calendar {} 

有爲什麼像第一個代碼示例中那樣導入的實際原因不會是編譯時錯誤?

+0

這不是多餘的;這是無效的。據說,我很確定這是合法的,因爲語言規範並不禁止它。可能這是語言設計者沒有考慮的情況。 – davmac

+0

你誤讀了JLS。它不禁止導入與頂級類相同的名稱,如果「編譯單元還聲明瞭簡單名爲'n'的頂級[sic]類型」,則禁止導入名稱'n'。這不是你展示的情況。 –

+0

@LewBloch我不明白你指出的區別。請你能舉一個例子來證明這個區別嗎? –

回答

3

我能想出的唯一情況是,你有一個兩次(或更多)-nested具有相同名稱的進口類:

import java.util.Calendar; 

class Demo { 
    static class Nested { 
    static class Calendar {} 

    static void useNested() { 
     System.out.println(Calendar.class); // Demo.Nested.Calendar 
    } 
    } 

    static void useImported() { 
    System.out.println(Calendar.class); // java.util.Calendar 
    } 

    public static void main(String[] args) { 
    Nested.useNested(); 
    useImported(); 
    } 
} 

Ideone demo

在這種情況下, ,嵌套的CalendarNested類的範圍之外不會自動可見,因此導入的Calendar類在外部使用,例如在useImported方法中。

我不會真的形容這是一個「實用」的使用,雖然 - 它只是普通的混亂哪個在每個上下文中使用,絕對值得避免。不過,它仍然讓我感興趣的是這種情況的存在。


我假設有另一個類似的情況:

import java.util.Calendar; 

class Demo { 
    static void useImported() { ... } 
} 

class Demo2 { 
    class Calendar {} 

    static void useNested() { ... } 
} 

(其中這些類在相同的編譯單元)。基本上和上面一樣。

0

我想,如果導入一個類,它是在編譯單元的全球空間可見。但是,如果您將編譯單元或頂級類的名稱與導入的名稱相同,那麼您基本上與導入相沖突,因此JVM知道哪個是哪一個是不明確的。並且自從編譯一個類以來,它會給導入一個錯誤。

而且,當它的另一個類中,你那邊陰影進口。它與全局/類級別變量和方法級別變量隱藏它們(如果使用相同名稱定義的)相似。

希望這會有所幫助。

+0

「,因此它對於JVM來說是模棱兩可的。」它並不含糊,你根本無法引用導入的類,因此它被阻止。這就像阻止像「」instanceof Integer「這樣的東西:它不是JVM的含糊不清,它可能只是表示程序員錯誤。 –

+0

@AndyTurner - 我解釋了假設JVM是否允許導入和頂級類名在同一編譯單元中相同。對不起,也許我不清楚。 –

+0

是的,我明白了,並且我在說它並不含糊:它是*冗餘的*,與''「'instanceof Integer'是編寫'false'的冗餘方式相同,因此編譯器不允許。 –

相關問題