2014-07-07 21 views
17

Il metodo principale tenta di accedere a var, ma restituisce una chiamata ambigua. Perché? Variabile di istanza var in Base1 non è accessibile (visibile?) Dal contesto statico in ogni caso.Chiamata ambigua dal contesto statico in Java

class Base1 { 
     int var; 
    } 

    interface Base2 { 
     public static final int var = 0; 
    } 

    class Test extends Base1 implements Base2 { 
     public static void main(String args[]) { 
      System.out.println("var:" + var); 
     } 
    } 
+0

@Pablo, il pacchetto non ha importanza. Basta inserire lo snippet di codice in un unico file e vedere il risultato. – AlexR

+1

@AlexR "Errore - Almeno una classe pubblica è richiesta nel file principale" – Unihedron

+0

Bene, rendi pubblica una delle classi. Non questo è il problema. – AlexR

risposta

17

Il JLS rule for field access ambiguity è

Se gli identificatori diversi accessibili (§6.6) campi membro a tipo T, quindi l'accesso al campo è ambiguo e si verifica un errore in fase di compilazione .

E on the subject of accessibility

Un utente (classe, interfaccia, un campo o metodo) di un tipo di riferimento, o un costruttore di un tipo di classe, è accessibile solo se il tipo è accessibile e il membro o il costruttore è dichiarato per consentire l'accesso:

non fa una distinzione sul fatto che il campo di istanza di accesso potrebbe causare un errore di compilazione in un contesto static.

Nota che si potrebbe avere avuto

public static void main(String args[]) { 
    Test test = new Test(); 
    System.out.println("var:" + test.var); 
} 

saresti ancora avere l'ambiguità.

3

Per rendere inequivocabile mettere il nome dell'interfaccia come prefisso di qualificazione:

class Test extends Base1 implements Base2 { 

     public static void main(String args[]) { 
      System.out.println("var:" + Base2.var); 
     } 
} 
+3

Penso che il poster stesse chiedendo il perché, non una soluzione alternativa – mxb

+0

A volte il compilatore non si comporta in modo intelligente come ci aspettiamo che faccia. Potrebbe accadere che l'autore del codice significasse il campo non statico 'Base2.var' In questo caso è ambiguo (e sbagliato). (D'altra parte, è meglio scrivere codice non impegnativo in quanto il cervello umano ha bisogno di una certa capacità per capirlo: basta scrivere un codice che un idiota capisca, e anche il compilatore lo capisce :) –

1

Inizialmente nel passaggio uno il compilatore cercherà var variabile nella classe che si estende e l'interfaccia implementata. Poiché trova una variabile in entrambi i punti del secondo passaggio, mostra un'ambiguità.

1

I contesti statici statici e non non escludono di come sono ammesse le variabili per essere accessibili

i modificatori di accesso sono quelle che in realtà governano questo ...

cambiamento il modificatore di accesso per var in Base1 a privato e l'ambiguità scompare, anche se questo potrebbe non essere il modo in cui si desidera che si modifichino ma i modfatori effettivamente dettano il riferimento alle variabili di istanza piuttosto che al contesto statico senza contesti statici.

class Base1 { 
    private int var; 
    //static int var=5; 
} 

interface Base2 { 
    public static final int var = 0; 
} 

class ambiguousNonStaticCall extends Base1 implements Base2 { 
    public static void main(String args[]) { 
     System.out.println("var:" + var); 
    } 
} 

Il codice sopra riportato è valido.