paradise papers panama java variables scope shadowing

java - paradise - panama papers



pregunta sobre el alcance variable y el sombreado en Java (6)

Tengo esta situación que no puedo entender sobre el sombreado. Por ejemplo, el siguiente código

class Foo { int a = 5; void goFoo(int a) { // No problem naming parameter as same as instance variable for (int a = 0; a < 5; a++) { } //Now the compiler complains about the variable a on the for loop // i thought that the loop block had its own scope so i could shadow // the parameter, why the compiler didnt throw an error when i named // the parameter same as the instance variable? } }

Gracias por tu paciencia.


El alcance de la variable también depende de la jerarquía del bloque.

es decir, si lo usa así

void goFoo(int a) { // No problem naming parameter as same as instance variable for (int b = 0; b < 5; b++) { } //Now the compiler complains about the variable a on the for loop // i thought that the loop block had its own scope so i could shadow // the parameter, why the compiler didnt throw an error when i named // the parameter same as the instance variable? int b; // you can do this. }

Es decir, si una variable se declara en el bloque externo, entonces no se puede declarar lo mismo en el bloque interno. a la inversa, puedes hacerlo.


El problema no es que el bucle esté sombreando el campo de clase, el nombre ya está siendo utilizado por el parámetro.

Dos opciones: una es cambiar el ciclo:

for (a = 0; a < 5; a++) { }

Esto usa el parámetro como la variable de índice. No está claro por qué tendrías un parámetro, pero de todos modos ...

La otra opción es cambiar el nombre de la variable de bucle o el parámetro a otra cosa.


No está ocultando, es un conflicto aquí. Ambas están en el alcance del método. No se pueden definir dos variables del mismo nombre en el mismo ámbito.


Pero no declaras la segunda "a" en ese nuevo ámbito, como muestra tu código. Está en el alcance del bloque goFoo () en sí mismo.


Puede hacer que una variable local sombree una instancia / variable estática, pero no puede hacer que una variable local (su contador de bucle) ensombrezca otra variable o parámetro local (su parámetro).

De la Especificación del lenguaje Java, sección 14.4.3 :

Si un nombre declarado como una variable local ya está declarado como un nombre de campo, entonces esa declaración externa se sombreará (§6.3.1) en todo el ámbito de la variable local.

Tenga en cuenta la parte "nombre del campo": especifica que tiene que ser un campo sombreado.

Y de la sección 8.4.1 :

El alcance de un parámetro de un método (§8.4.1) o constructor (§8.8.1) es el cuerpo completo del método o constructor.

Estos nombres de parámetros no se pueden volver a declarar como variables locales del método, o como parámetros de excepción de cláusulas de captura en una instrucción try del método o constructor.

(Continúa hablando sobre clases locales y clases anónimas, pero son irrelevantes en su caso).


void goFoo(int a) { for (int a = 0; a < 5; a++) { } }

Esto es similar a

void goFoo() { int a; for (int a = 0; a < 5; a++) { } }

por lo que la declaración múltiple de a en el mismo ámbito, no es aceptable.

o simplemente es similar a

void goFoo() { int a; int a; }

Ver también