Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

262
Vistas
¿Por qué Java requiere una conversión explícita en una variable final si se copió de una matriz?

Comenzando con el siguiente código...

 byte foo = 1; byte fooFoo = foo + foo;

Cuando intento compilar este código obtendré el siguiente error...

Error: (5, 27) java: tipos incompatibles: posible conversión con pérdida de int a byte

... pero si foo es definitivo...

 final byte foo = 1; final byte fooFoo = foo + foo;

el archivo se compilará con éxito.

Pasando al siguiente código...

 final byte[] fooArray = new byte[1]; fooArray[0] = 1; final byte foo = fooArray[0]; fooArray[0] = 127; System.out.println("foo is: " + foo);

... imprimirá

 foo is: 1

... lo cual está bien. El valor se copia a una variable final y ya no se puede cambiar. Jugar con el valor en la matriz no cambia el valor de foo (como se esperaba...).

¿Por qué lo siguiente requiere un yeso?

 final byte[] fooArray = new byte[1]; fooArray[0] = 1; final byte foo = fooArray[0]; final byte fooFoo = foo + foo;

¿En qué se diferencia esto del segundo ejemplo en esta pregunta? ¿Por qué el compilador me da el siguiente error?

Error: (5, 27) java: tipos incompatibles: posible conversión con pérdida de int a byte

¿Cómo puede suceder esto?

about 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

El JLS ( §5.2 ) tiene reglas especiales para la conversión de asignaciones con expresiones constantes :

Además, si la expresión es una expresión constante ( §15.28 ) de tipo byte , short , char o int :

  • Se puede usar una conversión primitiva de restricción si el tipo de variable es byte , short o char , y el valor de la expresión constante se puede representar en el tipo de variable.

Si seguimos el enlace de arriba, vemos esto en la definición de expresión constante :

  • Literales de tipo primitivo y literales de tipo String
  • Los operadores aditivos + y -
  • Nombres simples (§6.5.6.1 ) que se refieren a variables constantes ( §4.12.4 ).

Si seguimos el segundo enlace de arriba, vemos que

Una variable de tipo primitivo o de tipo String , que es final e inicializada con una expresión constante en tiempo de compilación ( §15.28 ), se denomina variable constante .

De ello se deduce que foo + foo sólo se puede asignar a fooFoo si foo es una variable constante . Para aplicar eso a sus casos:

  • byte foo = 1; no define una variable constante porque no es final .

  • final byte foo = 1; define una variable constante , porque es final e inicializada con una expresión constante (un literal primitivo).

  • final byte foo = fooArray[0]; no define una variable constante porque no se inicializa con una expresión constante .

Tenga en cuenta que no importa si fooFoo es en sí mismo final .

about 4 years ago · Santiago Trujillo Denunciar

0

El valor 1 encaja muy bien en un byte; también 1+1; y cuando la variable es final, el compilador puede hacer un plegado constante . (en otras palabras: el compilador no usa foo al hacer esa operación +, sino los valores 1 "sin procesar")

Pero cuando la variable no es definitiva, entonces entran en juego todas las reglas interesantes sobre conversiones y promociones (consulte aquí ; desea leer la sección 5.12 sobre la ampliación de conversiones primitivas).

Para la segunda parte: hacer que una matriz sea final aún le permite cambiar cualquiera de sus campos; así que de nuevo; no es posible un plegado constante; para que la operación de "ampliación" vuelva a ponerse en marcha.

about 4 years ago · Santiago Trujillo Denunciar

0

De hecho, es lo que hace el compilador en el plegado constante cuando se usa con final , como podemos ver en el código de bytes:

 byte f = 1; // because compiler still use variable 'f', so `f + f` will // be promoted to int, so we need cast byte ff = (byte) (f + f); final byte s = 3; // here compiler will directly compute the result and it know // 3 + 3 = 6 is a byte, so no need cast byte ss = s + s; //---------------------- L0 LINENUMBER 12 L0 ICONST_1 // set variable to 1 ISTORE 1 // store variable 'f' L1 LINENUMBER 13 L1 ILOAD 1 // use variable 'f' ILOAD 1 IADD I2B ISTORE 2 // store 'ff' L2 LINENUMBER 14 L2 ICONST_3 // set variable to 3 ISTORE 3 // store 's' L3 LINENUMBER 15 L3 BIPUSH 6 // compiler just compute the result '6' and set directly ISTORE 4 // store 'ss'

Y si cambia su byte final a 127, también se quejará:

 final byte s = 127; byte ss = s + s;

en cuyo caso, el compilador calcula el resultado y lo sabe fuera de límite, por lo que aún se quejará de que son incompatibles.

Más:

Y aquí hay otra pregunta sobre el plegado constante con hilo:

about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda