2011-06-21 13 views
8

No soy nuevo en Java y C#. Pensé que entender el concepto de ámbito de variable hasta hace poco me hice esta pregunta en una entrevista:Una pregunta difícil de Java simple: alcance variable

public class Q{ //starting y scope 

    static int x = 11; 
    private int y = 33; // Just added a “private” modifier to make it clearer. 

    public static void main(String args[]){ 
     Q q = new Q(); 
     q.call(5); 
    } 

    public void call(int x){ 
     Q q = new Q(); 

     this.x = 22; 
     y = 44; 

     System.out.println("Output: " + Q.x); 
     System.out.println("Output: " + q.x); 
     System.out.println("Output: " + q.y); 
    } 

} //ending y scope 

Definir la salida de este programa.

Respondí a la pregunta durante la entrevista que la salida sería una excepción de tiempo de ejecución. A mi entender, y es declarado privado, y el método de instancia call() está tratando de acceder a la variable privada de la instancia y de otra instancia de la clase Q. ¿¡Cómo pudo suceder eso !? Sin embargo, responder incorrectamente esta pregunta no afectó demasiado mi entrevista porque este es el tipo de pregunta "compleja básica". Pero responder incorrectamente significa que la experiencia de Java de mis años necesita rehabilitación, ¡eso es terrible!

¿Alguien podría ayudarme en este asunto? ¡Sería muy apreciado!

+0

¿Tiene salida 11,22,33? –

+4

No estoy seguro de cómo esta es una pregunta "difícil". – R0MANARMY

+9

Diría que 22, 22, 33, 'x' es estático, ¿por qué no podría cambiarse por' this.x = 22'? – Kevin

Respuesta

24

Puede acceder a private miembros de su propia clase, incluso desde una instancia diferente de la clase.

+1

Mente = * Soplado * ... –

+1

+1 si no pudiera, sería casi imposible implementar 'Comparable'. – Qwerky

+1

@Qwerky: Supongamos que las personas codifican las variables como privadas :) –

8

private simplemente significa que no se puede acceder a los objetos de otra clase , no cualquier otro objetos. Entonces, un objeto Q puede acceder a los miembros privados de otro objeto Q.

[Tenga en cuenta que si esto fuera ilegal, esto desencadenaría un error de compilación, no una excepción de tiempo de ejecución.]

6

Las variables privadas son accesibles dentro del texto del programa de la clase declarante. No importa si una instancia intenta acceder a variables en otra instancia, siempre que el código esté dentro de la misma clase.

Desde el JLS section 6.6:

De lo contrario, si el miembro o constructor se declara privada, entonces se permite el acceso si y sólo si se produce dentro del cuerpo de la clase de nivel superior (§7.6) que encierra el declaración del miembro o constructor.

+0

¡Gracias! El enlace que compartiste realmente ayuda a – lixiang

3

private significa que las clases fuera de esta clase no pueden ver la variable. Dentro de esta definición de clase, se puede acceder a todos los métodos y variables.

3

Las restricciones de acceso deben aplicarse tiempo de compilación no en tiempo de ejecución, por lo que el compilador debe evitar compilar el código si fue incorrecto.

Pero se aplica un modificador de acceso en el nivel de clase, por lo que siempre puede acceder a un miembro privado de la clase en sí.

Cuando clona un objeto, esto a menudo es útil, ya que puede simplemente establecer una serie de valores en el clon directamente, lo que podría haber sido difícil de obtener de lo contrario. También cuando se comparan objetos con un método Equals, puede ser bastante útil que sea la clase, no la instancia, la que define las restricciones de acceso.

+0

¡Genial! Tengo mucho que aprender, creo :) – lixiang

2

Creo que habrá un problema de compilación porque el atributo static int x = 11 se declara estático y en el método call, se accede a la variable x por this.No puede hacer un this a una variable estática en una clase.

No hay ningún problema con el miembro privado y.

+3

"No se puede hacer esto a una variable estática en una clase". ¿¿¿Por qué no??? Puede usar la palabra clave "this" para acceder a cualquier variable o método dentro de una clase, sin importar los modificadores que tenga. –

+0

Como dijo Filipe, es posible. Sin embargo, no se recomienda y generará una advertencia de compilación. –

+0

Sí, fui a leer nuevamente la especificación e intenté algunas pruebas. Estaba equivocado. – Dimitri

3

Como ya se señaló, los miembros privados de las otras instancias son accesibles desde la clase. Además, fue incorrecta sobre la excepción de tiempo de ejecución: no habrá excepción en tiempo de ejecución incluso si modifica el código para que intente acceder a un miembro privado de otra clase, el código no podrá compilarse.

2

¡La respuesta correcta de "entrevista" es que quien haya escrito código como este debe ser despedido! Nombre de clase pésimo, comentarios inútiles sobre el alcance y; el uso no estándar de "esto" que realmente solo debería usarse para variables de instancia, no para variables de clase; reutilizando 'q' en los métodos main y call.

Me recuerda a los concursos de C++ ofuscados, exactamente el tipo de tonterías que Java fue diseñado para evitar.

Peor que esto, sin embargo, es que es muy difícil decir a partir de los comentarios y las respuestas cuál debe ser el resultado del programa. ¿Voy por el '6' en el comentario de Kevin?

Ojalá un administrador refaccionase todo esto. Y le diría a un entrevistador (si esto realmente es una pregunta de la entrevista, que dudo) que debemos ejecutar el código, obtener las respuestas y luego crear una prueba simple para confirmar que las respuestas no cambian cuando refactorizamos el código para ajustarse al uso estándar.

+0

El punto de las preguntas de la entrevista es: ¿qué tan bien sabes lo que hará Java antes de ejecutarlo? Es mucho más rápido y económico escribir un código funcional cuando no necesita llamar a un "administrador" para darle las respuestas.Si su respuesta en una entrevista es llamar a un "administrador", entonces mi siguiente pregunta es "¿por qué debería pagarle en lugar de solo pagarle al administrador?" – mwengler

+0

Esto realmente fue una pregunta de entrevista, decididamente hicieron que esta clase se viera así. Después de casi un año, cuando volví a mirar esta pregunta (gracias a Ed por comentar ahora) me doy cuenta de que esta pregunta no tiene demasiado sentido ya que el año pasado de ser un verdadero programador casi nunca he usado Java en de esta manera. Pero sí, @mwengler, el objetivo de la pregunta era simplemente probar cuán bien conoces a Java y obviamente no conocía Java hace tan solo un año: p – lixiang