2010-01-13 24 views
11

¿Cuál es el punto de tener una variable de instancia como final?punto de tener una variable de instancia como final?

¿No es mejor tener esa variable configurada como una variable final estática entonces?

causa si no puede ser cambiado por ninguno de los objetos, entonces es lo mismo que una variable de clase (estática), ¿verdad?

+0

http://renaud.waldura.com/doc/java/final-keyword.shtml –

Respuesta

20

Nop. static significa que es el mismo en todas las instancias de la clase. final significa que no es asignable después de su asignación inicial. Entonces dos instancias podrían tener diferentes valores para una variable final no estática.

Hay muchas razones por las que puede querer hacer una variable final; uno de los mejores es la claridad. Si leo un método y advierto que el foo es definitivo, no tengo que preocuparme de dónde está cambiando a continuación, porque no lo está; no puede Puedo hacer más cambios al código con las variables finales con menos preocupación ("¿Cambié el valor de foo antes o después de la barra, y qué importa?") Porque sé que algunas variables no están sujetas a cambios. También enfoca mi atención en las variables que están sujetas a cambios, y son las que merecen más atención.

+1

pero ¿no asigna un valor a la variable de instancia final cuando escribe la clase? entonces eso significa que todos los objetos usarán ese valor y no pueden cambiar? o estoy equivocado? – ajsie

+5

No necesariamente: se puede asignar en el constructor. – danben

1

Evita que otros programadores de hacer cosas estúpidas que no deben intentar hacer de todos modos ...

2

Puede asignarle un valor que sea específico de la instancia del objeto, que no se puede hacer con una variable de clase estática.

+0

, quiere decir que cuando escribo la clase solo la declaro como definitiva. y cuando he instanciado la clase y llamo a un método, ¿el método le asignará un valor que no se puede cambiar? – ajsie

+0

Creo que necesita asignar un valor en el constructor, de lo contrario, el compilador lanzará un error. –

3

dos razones:

1) Desde el punto de vista de diseño de clase, que permite a un programador para confiar en el hecho de que el campo no va a cambiar desde instanciación - llamado "immutable object". El tutorial de Java dice:

Los objetos inmutables son particularmente útiles en aplicaciones concurrentes. Como no pueden cambiar el estado, no pueden corromperse por la interferencia de hilo o observarse en un estado incoherente.

Los objetos inmutables son la base de varios estilos de programación, p. programación funcional pura.

2) El segundo motivo son las optimizaciones de JVM. Si todos los campos son definitivos, JVM sabe que el estado del objeto no puede modificarse y, por lo tanto, puede realizar muchas optimizaciones, p. omitiendo los controles de seguridad del hilo, etc.

+1

@Ondra: el hecho de que JVM * pueda * (o no) optimizar campos 'finales', etc. es un problema secundario. La motivación principal para usar 'final' debe ser hacer que su código sea más robusto. (Y recuerde el consejo de que es una mala idea micro-optimizar Java porque el compilador JIT puede hacer un mejor trabajo si no lo hace) –

+0

@Stephen: 1) Cubrí el aspecto "robusto" de la final en el segundo párrafo. 2) Hacer que sus pequeños objetos de datos sean inmutables definitivamente no es una microoptimización, puede proporcionar importantes aumentos de rendimiento. "Una de las razones más comunes para no hacer que una clase sea inmutable es la creencia de que hacerlo podría comprometer el rendimiento. Aunque esto es cierto algunas veces, a menudo no es así, y algunas veces el uso de objetos inmutables sorprendente, ventajas de rendimiento ". –

4

Creo que se está pensando en caso sencillo como:

private final int num = 3; 

que puede ser mejor escribir como:

private static final int NUM = 3; 

Sin embargo, a menudo tendrá referencias a objetos que son mutables, y por lo tanto, no se puede compartir entre las clases:

private final List<Node> children = new ArrayList<Children>(); 

O tal vez, un valor pasado a o derivados de los constructores:

public final class MyThing { 
     private final String name; 
     public MyThing(String name) { 
      this.name = name; 
     } 
     [...] 
} 

Nota: final campos se pueden asignar en los constructores (o initialiser ejemplo), no sólo como parte de la declaración.

+0

Su último ejemplo muestra una clase 'final'. Eso no tiene nada que ver con la mutabilidad, y solo confundirá al lector novato. –

Cuestiones relacionadas