traductores traductor traducir traducción traduccion tipos son que profesionales para libros las interpretacion ingles herramientas español cuales java final

java - traductor - que es la traduccion pdf



¿Cómo funciona la palabra clave "final" en Java?(Todavía puedo modificar un objeto.) (18)

  1. Dado que la variable final no es estática, se puede inicializar en el constructor. Pero si lo hace estático, no puede ser inicializado por el constructor (porque los constructores no son estáticos).
  2. No se espera que la adición a la lista se detenga al hacer la lista final. final solo une la referencia a un objeto particular. Usted es libre de cambiar el "estado" de ese objeto, pero no el objeto en sí.

En Java usamos final palabra clave final con variables para especificar que sus valores no deben cambiarse. Pero veo que puedes cambiar el valor en el constructor / métodos de la clase. Nuevamente, si la variable es static entonces es un error de compilación.

Aquí está el código:

import java.util.ArrayList; import java.util.List; class Test { private final List foo; public Test() { foo = new ArrayList(); foo.add("foo"); // Modification-1 } public static void main(String[] args) { Test t = new Test(); t.foo.add("bar"); // Modification-2 System.out.println("print - " + t.foo); } }

El código anterior funciona bien y no hay errores.

Ahora cambia la variable como static :

private static final List foo;

Ahora es un error de compilación. ¿Cómo funciona realmente esta final ?


A continuación se presentan diferentes contextos donde se utiliza final.

Variables finales Una variable final solo se puede asignar una vez. Si la variable es una referencia, esto significa que la variable no se puede volver a vincular para hacer referencia a otro objeto.

class Main { public static void main(String args[]){ final int i = 20; i = 30; //Compiler Error:cannot assign a value to final variable i twice } }

la variable final puede asignarse un valor más tarde (no es obligatorio asignar un valor cuando se declara), pero solo una vez.

Clases finales Una clase final no puede ser extendida (heredada)

final class Base { } class Derived extends Base { } //Compiler Error:cannot inherit from final Base public class Main { public static void main(String args[]) { } }

Métodos finales Un método final no puede ser anulado por subclases.

//Error in following program as we are trying to override a final method. class Base { public final void show() { System.out.println("Base::show() called"); } } class Derived extends Base { public void show() { //Compiler Error: show() in Derived cannot override System.out.println("Derived::show() called"); } } public class Main { public static void main(String[] args) { Base b = new Derived();; b.show(); } }


Cuando lo hace estático final, debe inicializarse en un bloque de inicialización estático

private static final List foo; static { foo = new ArrayList(); } public Test() { // foo = new ArrayList(); foo.add("foo"); // Modification-1 }


En primer lugar, el lugar en su código donde está inicializando (es decir, asignando por primera vez) foo está aquí:

foo = new ArrayList();

foo es un objeto (con el tipo Lista), por lo que es un tipo de referencia , no un tipo de valor (como int). Como tal, contiene una referencia a una ubicación de memoria (por ejemplo, 0xA7D2A834) donde se almacenan los elementos de la Lista. Líneas como esta

foo.add("foo"); // Modification-1

no cambie el valor de foo (que, de nuevo, es solo una referencia a una ubicación de memoria). En su lugar, simplemente agregan elementos a esa ubicación de memoria referenciada. Para violar la palabra clave final , deberías intentar volver a asignar foo de la siguiente manera:

foo = new ArrayList();

Eso te daría un error de compilación.

Ahora, con eso fuera del camino, piense en lo que sucede cuando agrega la palabra clave estática .

Cuando NO tiene la palabra clave estática, cada objeto que crea una instancia de la clase tiene su propia copia de foo. Por lo tanto, el constructor asigna un valor a una copia nueva y en blanco de la variable foo, que está perfectamente bien.

Sin embargo, cuando TIENE la palabra clave estática, solo existe un foo en la memoria asociada con la clase. Si fueras a crear dos o más objetos, el constructor intentaría volver a asignar ese foo cada vez, violando la palabra clave final .


Esta es una pregunta favorita de la entrevista . Con estas preguntas, el entrevistador intenta descubrir qué tan bien entiende el comportamiento de los objetos con respecto a los constructores, los métodos, las variables de clase (variables estáticas) y las variables de instancia.

import java.util.ArrayList; import java.util.List; class Test { private final List foo; public Test() { foo = new ArrayList(); foo.add("foo"); // Modification-1 } public void setFoo(List foo) { //this.foo = foo; Results in compile time error. } }

En el caso anterior, hemos definido un constructor para ''Prueba'' y le dimos un método ''setFoo''.

Acerca del constructor: el constructor se puede invocar solo una vez por creación de objeto utilizando la new palabra clave. No puede invocar el constructor varias veces, porque el constructor no está diseñado para hacerlo.

Acerca del método: se puede invocar un método tantas veces como desee (incluso nunca) y el compilador lo sabe.

escenario 1

private final List foo; // 1

foo es una variable de instancia . Cuando creamos un objeto de clase de Test , la variable de instancia foo se copiará dentro del objeto de la clase de Test . Si asignamos foo dentro del constructor, entonces el compilador sabe que el constructor se invocará solo una vez, por lo que no hay problema en asignarlo dentro del constructor.

Si asignamos foo dentro de un método, el compilador sabe que un método puede llamarse varias veces, lo que significa que el valor tendrá que cambiarse varias veces, lo que no está permitido para una variable final . ¡Así que el compilador decide que el constructor es una buena elección! Puede asignar un valor a una variable final solo una vez.

Escenario 2

private static final List foo = new ArrayList();

foo es ahora una variable estática . Cuando creamos una instancia de clase de Test , foo no se copiará al objeto porque foo es estático. Ahora foo no es una propiedad independiente de cada objeto. Esta es una propiedad de la clase de Test . Pero foo puede ser visto por múltiples objetos y si cada objeto que se crea usando la new palabra clave que invocará el constructor de Test que cambia el valor en el momento de la creación de múltiples objetos (Recuerde que static foo no se copia en cada objeto, pero Se comparte entre varios objetos.)

Escenario 3

t.foo.add("bar"); // Modification-2

Por encima de la Modification-2 es de su pregunta. En el caso anterior, no está cambiando el primer objeto referenciado, pero está agregando contenido dentro de foo que está permitido. El compilador se queja si intenta asignar una new ArrayList() a la variable de referencia foo .
Regla Si ha inicializado una variable final , entonces no puede cambiarla para referirse a un objeto diferente. (En este caso ArrayList )

las clases finales no pueden ser subclasificadas
Los métodos finales no pueden ser anulados. (Este método está en superclase)
Los métodos finales pueden anular. (Lea esto en forma gramatical. Este método está en una subclase)


Esta es una muy buena pregunta de entrevista. A veces incluso pueden preguntarte cuál es la diferencia entre un objeto final y un objeto inmutable.

1) Cuando alguien menciona un objeto final, significa que la referencia no se puede cambiar, pero su estado (variables de instancia) se puede cambiar.

2) Un objeto inmutable es aquel cuyo estado no se puede cambiar, pero su referencia se puede cambiar. Ex:

String x = new String("abc"); x = "BCG";

la variable de referencia x se puede cambiar para que apunte a una cadena diferente, pero el valor de "abc" no se puede cambiar.

3) Las variables de instancia (campos no estáticos) se inicializan cuando se llama a un constructor. Así que puedes inicializar valores para tus variables dentro de un constructor.

4) "Pero veo que puede cambiar el valor en el constructor / métodos de la clase". - No puedes cambiarlo dentro de un método.

5) Se inicializa una variable estática durante la carga de clases. Por lo tanto, no se puede inicializar dentro de un constructor, se debe hacer incluso antes. Por lo tanto, debe asignar valores a una variable estática durante la declaración.


La palabra clave final en java se utiliza para restringir al usuario. La palabra clave final Java se puede utilizar en muchos contextos. La final puede ser:

  1. variable
  2. método
  3. clase

La palabra clave final se puede aplicar con las variables, una variable final que no tiene valor, se llama variable final blanco o variable final inicializar. Solo se puede inicializar en el constructor. La variable final blanco también puede ser static , que se inicializará solo en el bloque static .

Variable final de Java:

Si crea una variable como final , no puede cambiar el valor de final variable final (será constante).

Ejemplo de variable final

Hay una variable final límite de velocidad, vamos a cambiar el valor de esta variable, pero no se puede cambiar porque la variable final una vez asignado un valor nunca se puede cambiar.

class Bike9{ final int speedlimit=90;//final variable void run(){ speedlimit=400; // this will make error } public static void main(String args[]){ Bike9 obj=new Bike9(); obj.run(); } }//end of class

Clase final de Java:

Si haces cualquier clase como final , no puedes extenderla .

Ejemplo de clase final

final class Bike{} class Honda1 extends Bike{ //cannot inherit from final Bike,this will make error void run(){ System.out.println("running safely with 100kmph"); } public static void main(String args[]){ Honda1 honda= new Honda(); honda.run(); } }

Método final de Java:

Si crea algún método como definitivo, no puede anularlo .

Ejemplo del método final (run () en Honda no puede anular run () en Bike)

class Bike{ final void run(){System.out.println("running");} } class Honda extends Bike{ void run(){System.out.println("running safely with 100kmph");} public static void main(String args[]){ Honda honda= new Honda(); honda.run(); } }

Compartido desde: http://www.javatpoint.com/final-keyword


La palabra clave final indica que una variable solo se puede inicializar una vez. En su código, solo está realizando una inicialización de final, por lo que se cumplen los términos. Esta declaración realiza la única inicialización de foo . Tenga en cuenta que final ! = Inmutable, solo significa que la referencia no puede cambiar.

foo = new ArrayList();

Cuando declara foo como static final la variable debe inicializarse cuando la clase está cargada y no puede confiar en la creación de instancias (también llamada call to constructor) para inicializar foo ya que los campos estáticos deben estar disponibles sin una instancia de una clase. No hay garantía de que se haya llamado al constructor antes de usar el campo estático.

Cuando ejecuta su método en el escenario static final la clase de Test se carga antes de instanciar t en este momento, no hay una instancia de foo lo que significa que no se ha inicializado, por lo que foo se establece en el valor predeterminado para todos los objetos, que es null . En este punto, asumo que su código lanza una NullPointerException cuando intenta agregar un elemento a la lista.


La palabra clave final se puede interpretar de dos maneras diferentes dependiendo de lo que se usa en:

Tipos de valor: Para int s, double s, etc., se asegurará de que el valor no pueda cambiar,

Tipos de referencia: para las referencias a objetos, final garantiza que la referencia nunca cambiará, lo que significa que siempre se referirá al mismo objeto. No ofrece ninguna garantía sobre los valores dentro del objeto que se refiere a permanecer igual.

Como tal, final List<Whatever> foo; asegura que foo siempre hace referencia a la misma lista, pero el contenido de dicha lista puede cambiar con el tiempo.


Lee todas las respuestas.

Hay otro caso de usuario donde se puede usar la palabra clave final , es decir, en un argumento de método:

public void showCaseFinalArgumentVariable(final int someFinalInt){ someFinalInt = 9; // won''t compile as the argument is final }

Puede ser utilizado para variables que no deben ser cambiadas.


Pensé en escribir una respuesta actualizada y en profundidad aquí.

final palabra clave final se puede utilizar en varios lugares.

  1. clases

Una final class significa que ninguna otra clase puede extender esa clase final. Cuando Java Run Time ( JRE ) sabe que una referencia de objeto está en el tipo de una clase final (por ejemplo, F), sabe que el valor de esa referencia solo puede estar en el tipo de F.

Ex:

F myF; myF = new F(); //ok myF = someOther; //someOther cannot be in type of a child class of F. //because F cannot be extended.

Entonces, cuando ejecuta cualquier método de ese objeto, ese método no necesita resolverse en tiempo de ejecución utilizando una tabla virtual . es decir, el polimorfismo en tiempo de ejecución no se puede aplicar. Así que el tiempo de ejecución no se preocupa por eso. Lo que significa que ahorra tiempo de procesamiento, lo que mejorará el rendimiento.

  1. metodos

Un final method de cualquier clase significa que cualquier clase secundaria que extienda esa clase no puede anular esos métodos finales. Por lo tanto, el comportamiento del tiempo de ejecución en este escenario también es bastante similar al comportamiento anterior que mencioné para las clases.

  1. Campos, variables locales, parámetros del método.

Si uno especificó cualquier tipo de lo anterior como final , significa que el valor ya está finalizado, por lo que el valor no se puede cambiar .

Ex:

Para campos, parámetros locales.

final FinalClass fc = someFC; //need to assign straight away. otherwise compile error. final FinalClass fc; //compile error, need assignment (initialization inside a constructor Ok, constructor can be called only once) final FinalClass fc = new FinalClass(); //ok fc = someOtherFC; //compile error fc.someMethod(); //no problem someOtherFC.someMethod(); //no problem

Para parametros de metodo

void someMethod(final String s){ s = someOtherString; //compile error }

Esto simplemente significa que el valor del valor de referencia final no se puede cambiar. Es decir, solo se permite una inicialización. En este escenario, en tiempo de ejecución, ya que JRE sabe que los valores no se pueden cambiar, carga todos estos valores finalizados (de referencias finales) en la memoria caché L1 . Porque no es necesario volver a cargar una y otra vez desde la memoria principal . De lo contrario, se carga en la memoria caché L2 y realiza el tiempo de carga desde la memoria principal. Así que también es una mejora de rendimiento.

Por lo tanto, en los 3 escenarios anteriores, cuando no hemos especificado la palabra clave final en los lugares que podemos usar, no debemos preocuparnos, las optimizaciones del compilador lo harán por nosotros. También hay muchas otras cosas que las optimizaciones del compilador hacen por nosotros. :)


Por encima de todo son correctos. Además, si no desea que otros creen subclases de su clase, declare su clase como final. Luego se convierte en el nivel de hoja de su jerarquía de árbol de clases que nadie puede extender más. Es una buena práctica evitar una gran jerarquía de clases.


Si foo static, debe inicializarlo en el constructor de la clase (o en línea donde lo defina) como en los siguientes ejemplos.

Constructor de clase (no instancia):

private static final List foo; static { foo = new ArrayList(); }

En línea:

private static final List foo = new ArrayList();

El problema aquí no es cómo funciona el modificador final , sino cómo funciona el modificador static .

El modificador final impone una inicialización de su referencia en el momento en que finaliza la llamada a su constructor (es decir, debe inicializarla en el constructor).

Cuando inicializa un atributo en línea, se inicializa antes de que se ejecute el código que ha definido para el constructor, por lo que obtiene los siguientes resultados:

  • si foo es static , foo = new ArrayList() se ejecutará antes de que se ejecute el constructor static{} que ha definido para su clase
  • si foo no es static , foo = new ArrayList() se ejecutará antes de que se ejecute su constructor

Cuando no inicia un atributo en línea, el modificador final impone su inicialización y debe hacerlo en el constructor. Si también tiene un modificador static , el constructor en el que tendrá que inicializar el atributo es el bloque de inicialización de la clase: static{} .

El error que obtiene en su código es el hecho de que static{} se ejecuta cuando se carga la clase, antes de que se ejemplifique un objeto de esa clase. Por lo tanto, no habrá inicializado foo cuando se cree la clase.

Piense en el bloque static{} como un constructor para un objeto de tipo Class . Aquí es donde debe hacer la inicialización de sus atributos de clase static final (si no se realiza en línea).

Nota al margen:

El modificador final asegura la constancia solo para tipos y referencias primitivas.

Cuando declara un objeto final , lo que obtiene es una referencia final a ese objeto, pero el objeto en sí no es constante.

Lo que realmente está logrando al declarar un atributo final es que, una vez que declara un objeto para su propósito específico (como la final List que ha declarado), ese y solo ese objeto se usará para ese propósito: no podrá para cambiar la List foo a otra List , pero aún puede alterar su List agregando / eliminando elementos (la List que está utilizando será la misma, solo que se modifique su contenido).


Siempre se le permite inicializar una variable final . El compilador se asegura de que puedas hacerlo solo una vez.

Tenga en cuenta que los métodos de llamada en un objeto almacenado en una variable final no tienen nada que ver con la semántica de final . En otras palabras: final es solo sobre la referencia en sí, y no sobre el contenido del objeto referenciado.

Java no tiene concepto de inmutabilidad de objetos; esto se logra diseñando cuidadosamente el objeto, y es un esfuerzo lejos de ser trivial.


Supongamos que tienes dos cajas de dinero, rojo y blanco. Usted asigna estas cajas de dinero solo a dos hijos y no se les permite intercambiar sus cajas. Así que tiene cajas de dinero rojas o blancas (final), no puede modificar la caja pero puede poner dinero en su caja. A nadie le importa (Modificación-2).


Vale la pena mencionar algunas definiciones directas:

Clases / Métodos

Puede declarar algunos o todos los métodos de una clase como final , para indicar que las subclases no pueden anular el método.

Variables

Una vez que se ha inicializado una variable final , siempre contiene el mismo valor.

final básicamente, evita sobrescribir o sobrescribir por nada (subclases, variable "reasignar"), según el caso.


final es una palabra clave reservada en Java para restringir al usuario y se puede aplicar a las variables, métodos, clases y variables locales de los miembros. Las variables finales a menudo se declaran con la palabra clave static en Java y se tratan como constantes. Por ejemplo:

public static final String hello = "Hello";

Cuando usamos la palabra clave final con una declaración de variable, el valor almacenado dentro de esa variable no puede cambiarse más tarde.

Por ejemplo:

public class ClassDemo { private final int var1 = 3; public ClassDemo() { ... } }

Nota : Una clase declarada como final no puede ser extendida o heredada (es decir, no puede haber una subclase de la súper clase). También es bueno tener en cuenta que los métodos declarados como finales no pueden ser reemplazados por subclases.

Los beneficios de usar la palabra clave final se tratan en este hilo .


La palabra clave final tiene una forma numerosa de usar:

  • Una clase final no puede ser subclasificada.
  • Un método final no puede ser anulado por subclases
  • Una variable final solo se puede inicializar una vez

Otro uso:

  • Cuando se define una clase interna anónima dentro del cuerpo de un método, todas las variables declaradas finales en el alcance de ese método son accesibles desde la clase interna

Una variable de clase estática existirá desde el inicio de la JVM y debe inicializarse en la clase. El mensaje de error no aparecerá si haces esto.