2012-07-05 12 views
10

Estaba viendo otra question sobre variables finales y noté que puede declarar variables finales sin inicializarlas (una variable blank final). ¿Hay alguna razón por la cual es deseable hacer esto y cuándo es ventajoso?¿Cuándo es apropiado usar variables finales en blanco?

+1

casi nunca. las finales en blanco no hacen nada. son variables que nunca pueden tener ningún valor significativo. cualquier compilador de Java que merezca la pena le dará una advertencia y/o error. –

+1

Esto puede ser útil cuando quiere inicializarlo en el constructor (basado en algunos parámetros de constructor). – sshannin

+0

Final es final ... si intenta hacer final int a = 2; a = 3; arrojará un error –

Respuesta

25

Esto es útil para crear objetos inmutables:

public class Bla { 
    private final Color color; 

    public Bla(Color c) {this.color = c}; 

} 

Bla es inmutable (una vez creado, no se puede cambiar porque el color es final). Pero aún puede crear varios Blas construyéndolos con varios colores.

Véase también this question por ejemplo.

EDITAR

Tal vez vale la pena añadir que un "final en blanco" tiene un significado muy específico en Java, que parece haber creado cierta confusión en los comentarios - CF Java Language Specification 4.12.4:

Un final en blanco es una variable final cuya declaración carece de un inicializador.

Luego debe asignar esa variable final en blanco en un constructor.

+2

Estaba pensando que tenía razón al decir no puedes hacer esto :) No sabía esto. +1 –

+0

concisa y clara. ¡Gracias! –

2

Puede hacer esto cuando no sabe cuál será el valor antes de la instrumentación de un objeto, solo necesita tener un valor asignado en su constructor.

Así es como se fabrica immutable objects y se utiliza en el patrón de generador.

class Builder{ 
    final BuilderContext context; 

    private Builder(BuilderContext context){ 
     this.context=context; 
    }  

    public static Builder New(){ 
     return new Builder(new BuilderContext()); 
    } 
+1

El compilador _se quejará de 'new' como nombre de método. –

+0

lo siento Lo cambiaré a Nuevo, lo escribí rápidamente –

+0

¿No debería declararse estático el método New()? @JohnKane – piepi

0

cuenta de que se puede declarar final las variables sin inicializar ellos

Tienes que inicializarlo después (por ejemplo en el constructor) por lo que suele estar vacío.

4

La propiedad final de la clase debe tener un valor asignado antes de que se cree el objeto. Entonces, el último punto donde puedes asignarles valor es el constructor.

Esto se utiliza con frecuencia para immutable objects.

public class Foo { 

    private final Bar bar; 

    public Foo(Bar bar) { 
    this.bar = bar; 
    } 

    public Bar getBar() { 
    return new Bar(bar); 
} 
} 

What wiki says about it

Defensive copying.

+0

Sí. Esto es a lo que se refiere una "final en blanco", según la cita de Wikipedia. –

+0

@LouisWasserman, no me di cuenta de que wiki lo describe. He agregado una referencia a Wiki pero, su "final en blanco" muestra que Wiki no es el mejor lugar para obtener conocimiento. ;-). –

+0

Espera, ¿qué? La respuesta aceptada a la pregunta que el OP enlazó incluía un enlace de Wikipedia, que tenía una cita que coincide con su respuesta. –

0

De Wikipedia

El final en blanco, el cual fue introducido en Java 1.1, es una variable cuya declaración definitiva carece de un inicializador. Una final en blanco solo se puede asignar una vez y se debe desasignar cuando se produce una asignación. Para hacer esto, un compilador de Java ejecuta un análisis de flujo para asegurar que, para cada asignación a una variable final en blanco, la variable definitivamente no esté asignada antes de la asignación; de lo contrario, se produce un error en tiempo de compilación.

En general, un compilador de Java se asegurará de que el final en blanco no se utilice hasta que se le asigne un valor y que una vez asignado un valor, la variable ahora final no pueda reasignarse a otro valor.

1

Las variables finales en blanco deben asignarse "en algún lugar" en el constructor. Un ejemplo bien construida:

public class Test { 
    final int sign; 
    public Test(String upDown) { 
     if (upDown.equals("up")) { 
      sign = +1; 
     } else { 
      sign = -1; 
     } 
    } 
} 
1

Un caso podría ser cuando se tiene un campo que desea declarar final, pero cuya asignación puede lanzar una excepción y desea ser capaz de tomar medidas si eso sucede:

class A { 
    final URLConnection conn; 
    A(String url) { 
    try { 
     this.conn = new URL(url).openConnection(); 
    } catch (IOException | MalformedURLException e) { 
     // Maybe this isn't fatal, so just handle the Exception 
     // here and move on happily 
    } 
    } 
} 
1

Utilice una variable final en blanco dentro de un método para mostrar que todas las rutas de código que usan la variable asignan esa variable exactamente una vez (o lanzan una excepción). Los compiladores Java garantizarán que se asigne una variable final en blanco antes de ser utilizada.

código de ejemplo en el interior de algún método:

final Foo foo; 
    if (condition1()) { 
    foo = makeFoo(1); 
    } else if (condition2()) { 
    throw new BarException(); 
    } else { 
    foo = makeFoo(-1); 
    } 
    ... 
    blahBlahBlah(foo); 

Usando variables finales en blanco le dice al lector siguiente del código que el compilador garantiza que alguien le asigna foo antes de llamar blahblahblah (foo).

La pregunta se refiere a "variables finales en blanco". La discusión de "campos en blanco finales" es una discusión diferente, e interesante por derecho propio.

Cuestiones relacionadas