2011-02-23 11 views
72
public class A 
{  
    private static final int x; 

    public A() 
    { 
     x = 5; 
    } 
} 
  • final significa que la variable sólo se puede asignar una vez (en el constructor).
  • static significa que es una instancia de clase.

No puedo ver por qué esto está prohibido. ¿Dónde interfieren esas palabras clave entre sí?Inicializar un campo static final en el constructor

Respuesta

149

Un constructor se llama cada vez que se crea una instancia de la clase. Por lo tanto, el código anterior significa que el valor de x se reinicializará cada vez que se cree una instancia. Pero debido a que la variable se declara final (y estática), sólo se puede hacer esto

class A {  
    private static final int x; 

    static { 
     x = 5; 
    } 
} 

Pero, si se quita estática, se le permite hacer esto:

class A {  
    private final int x; 

    public A() { 
     x = 5; 
    } 
} 

O esto:

class A {  
    private final int x; 

    { 
     x = 5; 
    } 
} 
+7

+1 para una respuesta clara y simple – sactiw

+12

Aparentemente, nadie se molestó en explicar que las variables estáticas son variables que existen en todas las instancias de una clase. Como tal, solo se pueden crear instancias una vez, cuando se carga la clase, no cuando potencialmente se construyen muchas instancias de la clase. – iheanyi

+1

Además, recomendaría simplemente asignar en la declaración en lugar de en un bloque estático. Es más limpio y probablemente sea lo que el OP quería hacer: 'private static final int x = 5;' – qwertzguy

15

variables estáticas finales se inicializan cuando se carga la clase. El constructor puede llamarse mucho más tarde, o no llamarse en absoluto. Además, el constructor se llamará varias veces (con cada objeto nuevo), por lo que el campo ya no puede ser final.

Si necesita una lógica personalizada para inicializar el campo final estático, que ponen en un bloque estático

+0

Ok, pero usted acaba de explicar lo que está sucediendo. Me pregunto por qué? Quiero decir, sin el final funciona, sin la estática funciona. entonces, ¿combinar ambos crea alguna nueva lógica? –

+3

@YaronLevi lo acaba de decir ... el campo estático es un miembro de la clase en sí. En su constructor está asignando un valor a la variable. La palabra final significa que solo puede asignar un valor a la variable UNA vez, en el código está asignando un valor a la variable cada vez que se crea una instancia de la clase, porque la variable es estática (un miembro de la clase). Si se deshace de la estática, puede asignarle un valor en el constructor ya que es una variable nueva cada vez. Si se deshace de la final, entonces solo se trata de una variable estática, a la que puede asignar un nuevo valor en cualquier momento. – user12345613

+1

@ user12345613 pon una buena explicación. Solo, ya sea trabajo final o estático; pero una vez reunidas, las fuerzas "estáticas finales" solo hay un campo para esa clase en todas las instancias y solo se puede inicializar una vez independientemente de la cantidad de instancias. – user908645

6

Piensa en lo que ocurre la segunda vez que creas un objeto. Intenta volver a establecerlo, lo que está expresamente prohibido por ser un final estático. Solo se puede establecer una vez para toda la clase, no para instancia.

Se debe ajustar el valor cuando se declara que

private static final x=5; 

Si necesita lógica adicional, o de instancias más complejas, esto se puede hacer en un bloque inicializador estático.

2

Piénselo. Usted puede hacer esto con su código:

A a = new A(); 
A b = new A(); // Wrong... x is already initialised 

Las formas correctas para inicializar x son:

public class A 
{  
    private static final int x = 5; 
} 

o

public class A 
{  
    private static final int x; 

    static 
    { 
     x = 5; 
    } 
} 
5

static significa que la variable es única en la aplicación. final significa que debe establecerse solo una vez.

Si lo configura en su constructor, permite establecer la variable más de una vez.

Por lo tanto, debe inicializarlo directamente o proponer un método estático para inicializarlo.

3

Final no significa que deba inicializarse en el constructor. Generalmente esto es lo que se hace:

private static final int x = 5; 

estática vez significa que la variable será compartida a través de múltiples instancias de la clase. Por ejemplo:

public class Car { 
    static String name; 
    public Car(String name) { 
     this.name = name; 
    } 
} 

... 

Car a = new Car("Volkswagen); 
System.out.println(a.name); // Produces Volkswagen 

Car b = new Car("Mercedes"); 
System.out.println(b.name); // Produces Mercedes 
System.out.println(a.name); // Produces Mercedes 

¿Lo tiene?

Cuestiones relacionadas