2009-03-24 12 views
7

¿Existe alguna solución para usar una variable final en un constructor de Java? El problema es que si inicializar un campo final como:Inicializar la variable final antes del constructor en Java

private final String name = "a name"; 

entonces no puedo usarlo en el constructor. Java primero ejecuta el constructor y luego los campos. ¿Hay alguna solución que me permita acceder al campo final en el constructor?

+1

Supongo que quiere cambiar el valor en el constructor ¿verdad? – webclimber

+2

Voté para cerrar porque, según entiendo, resulta que esto no es realmente un problema en absoluto. Lo que el OP intenta hacer debería funcionar. –

+1

El constructor ejecuta implícitamente la inicialización del campo inmediatamente antes de llamar al superconstructor. –

Respuesta

17

Realmente no entiendo su pregunta. Eso

public class Test3 { 
    private final String test = "test123"; 

    public Test3() { 
     System.out.println("Test = "+test); 
    } 

    public static void main(String[] args) { 
     Test3 t = new Test3(); 
    } 
} 

ejecuta de la siguiente manera:

$ javac Test3.java && java Test3 
Test = test123 
15

hacer la inicialización en el constructor, por ejemplo,

private final String name; 
private YourObj() { 
    name = "a name"; 
} 

Por supuesto, si realmente conoce el valor en el momento de declaración de variables, que tiene más sentido para que sea una constante, por ejemplo,

private static final String NAME = "a name"; 
2

En este caso, también puede marcar el campo como 'estático'.

+0

una forma sin un campo estático? – Tobias

+0

@Tobiask: ¿Por qué no quieres un campo estático? – sfossen

+0

Es inmutable, por lo que también podría hacerlo estático. –

1

En ese caso, también podría hacerlo estático. Y la convención de Java es nombrar tales constantes en ALL_CAPS.

1
private static final String name = getName(); 

donde getName() es una función estática que recibe el nombre.

+0

Tenga cuidado con este constructo si getName() no hace otra cosa que devolver una constante. Puede encontrar que la lógica utilizada por getName() puede no haber sido inicializada. – DJClayworth

3

Marcándolo estático, le permitirá usarlo en el constructor, pero desde que lo finalizó, no se puede cambiar.

private static final String name = "a_name"; 

es posible utilizar también un bloque de inicio estático.

private static final String name; 

static { name = "a_name"; } 

Si usted está tratando de modificar el valor en el constructor, entonces usted no puede asignar un valor predeterminado o tiene que hacerlo no es definitivo.

private String name = "a_name"; 
Foo(String name) 
{ 
    this.name = name; 
} 

o

private final String name; 

Foo(String name) 
{ 
    if(s == null) 
     this.name = "a_name"; 
    else 
     this.name = name; 
} 
0

no puedo usarlo en el constructor, mientras que Java se ejecuta primero el constructor una luego los campos ...

Esto no es correcto, campos se evalúan primero, de lo contrario no se podría acceder a ningún valor predeterminado de los miembros en sus constructores, ya que no se inicializarían. Esto hace trabajo:

public class A { 
    protected int member = 1; 
    public A() { 
     System.out.println(member); 
    } 
} 

La palabra clave última marca simplemente la constante de miembro, se trata como cualquier otro miembro de otra manera.

EDITAR: ¿Está intentando establecer el valor en el constructor?Eso no funcionaría, ya que el miembro es inmutable si se define como final.

+0

Técnicamente es el constructor el que (implícitamente) ejecuta la lógica de inicialización de campo. –

+0

Bueno, está bien. Sin embargo, los campos se evalúan primero. – soulmerge

2

Otra posibilidad es inicializar el campo en una instancia del bloque de inicialización:

public class Foo { 
     final String bar; 

     { 
       System.out.println("initializing bar"); 
       bar = "created at " + System.currentTimeMillis(); 
     } 

     public Foo() { 
       System.out.println("in constructor. bar=" + bar); 

     } 

     public static void main(String[] args) { 
       new Foo(); 
     } 
} 
5

Nos estamos alejando de la cuestión.

Sí, puede usar una variable private final. Por ejemplo:

public class Account { 
    private final String accountNumber; 
    private final String routingNumber; 

    public Account(String accountNumber, String routingNumber) { 
     this.accountNumber = accountNumber; 
     this.routingNumber = routingNumber; 
    } 
} 

Lo que esto significa es que la clase Cuenta tiene una dependencia en los dos Strings, cuenta y números de enrutamiento. Los valores de estos atributos de clase DEBEN establecerse cuando se construye la clase Account, y estos números no se pueden cambiar sin crear una nueva clase.

El modificador 'final' aquí hace que los atributos sean inmutables.

+2

Básicamente, tienes la oportunidad de establecer los valores en el constructor. Después de que el constructor finalice, los atributos son constantes. –

+2

Aparece el error "no puedo asignar un valor al valor de la variable final". –

Cuestiones relacionadas