java static ambiguous non-static

Llamada ambigua desde el contexto estático en Java



static ambiguous (4)

El método principal intenta acceder a var, pero da como resultado una llamada ambigua. ¿Por qué? La variable de instancia var en Base1 no es accesible (visible?) Desde el contexto estático de todos modos.

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); } }


Inicialmente, en el paso uno, el compilador buscará la variable var en la clase que extienda y la interfaz que implementará. Como encuentra una variable en ambos lugares en el paso dos, muestra ambigüedad.


La regla JLS para ambigüedad de acceso a campos es

Si el identificador nombra varios campos miembros accesibles (§6.6) en el tipo T , entonces el acceso al campo es ambiguo y se produce un error en tiempo de compilación.

Y en materia de accesibilidad.

Un miembro (clase, interfaz, campo o método) de un tipo de referencia, o un constructor de un tipo de clase, es accesible solo si el tipo es accesible y el miembro o constructor está declarado para permitir el acceso:

No hace una distinción acerca de si el acceso al campo de la instancia causaría un error de compilación en un contexto static .

Tenga en cuenta que podría haber tenido

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

Aún tendrías la ambigüedad.


Los contextos estáticos y no estáticos no determinan cómo se permite el acceso a las variables.

Los modificadores de acceso son los que realmente gobiernan esto ...

cambie el modificador de acceso para var en la Base1 a privado y la ambigüedad desaparecerá, aunque esta podría no ser la forma en que desea que se ajuste, pero los modificadores de acceso en realidad dictan la referencia a las variables de instancia en lugar de los contextos estáticos no estáticos.

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); } }

El código anterior compila bien.


Para que sea inequívoco, coloque el nombre de la interfaz como prefijo de calificación:

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