variable sirve que programacion para modificadores metodo diferencia acceso java arrays casting int byte

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



static programacion (3)

De hecho, es lo que el compilador hace en 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 conoce fuera de límite, por lo que aún se quejará de que son incompatibles.

Más:

Y here hay otra pregunta sobre el plegado constante con una cuerda:

Comenzando con el siguiente código ...

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

Cuando intente 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 final ...

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

El archivo se compilará correctamente.

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 del 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;

¿Cómo es esto diferente al 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 pasar esto?


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 estrecha si el tipo de la variable es byte , short o char , y el valor de la expresión constante es representable en el tipo de la variable.

Si seguimos el enlace anterior, los vemos 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 tipo String , que es final e inicializada con una expresión constante en tiempo de compilación ( §15.28 ), se llama variable constante .

Se deduce que foo + foo solo 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 si fooFoo es en sí mismo final no importa.


El valor 1 encaja perfectamente en un byte; también lo hace 1 + 1; y cuando la variable es final, el compilador puede hacer un plegado constante . (en otras palabras: el compilador no usa foo cuando hace esa operación +, pero los valores "en bruto" 1)

Pero cuando la variable no es final, entran en juego todas las reglas interesantes sobre conversiones y promociones (vea here ; desea leer la sección 5.12 sobre cómo ampliar las conversiones primitivas).

Para la segunda parte: hacer una matriz final aún le permite cambiar cualquiera de sus campos; así que de nuevo; no es posible doblar constantemente; para que la operación de "ensanchamiento" vuelva a funcionar.