¿Por qué en un interruptor de Java a través de una envoltura Integer, hace un caso 'carbón' no compila, pero la compilación está bien cuando el interruptor está sobre Byte?

ali gh:

No se compila:

void test(Integer x) {
      switch (x) {
          case 'a':
      }
}

Compila OK:

void test(Byte x) {
      switch(x) {
          case 'a':
      }
}
Stephen C:

Las razones son bastante complicados, pero todos ellos están en los detalles ( letra pequeña si se quiere) de la especificación del lenguaje Java.

En primer lugar, el JLS 14.11 dice lo siguiente acerca de switchlas declaraciones:

"Cada caso constante asociada con la instrucción switch debe ser compatible con la asignación del tipo de Expresión de la instrucción switch ( § 5.2 )."

Esto significa que 'a'necesita ser asignable a Integery Byte, respectivamente.

Pero eso no suena bien:

  • Se podría pensar que, puesto que 'a' debe ser asignable a una Integercausa char-> intasignación es legal. (Cualquier charvalor encajará en una int.)

  • Se podría pensar que, puesto que 'a' no debe ser asignable a una Bytecausa char-> byteasignación no es legal. (La mayoría de charlos valores no cabrán en un byte).

De hecho, ninguno de ellos es correcta. Para entender por qué, tenemos que leer lo que JLS 5.2 realmente acerca de lo que está permitido en contextos de asignación.

"Contextos de asignación permiten el uso de una de las siguientes :

  • una conversión de identidad (§5.1.1)
  • un ensanchamiento conversión primitiva (§5.1.2)
  • un ensanchamiento de conversión de referencia (§5.1.5)
  • una conversión de referencia ensanchamiento seguido por una conversión unboxing
  • una conversión de referencia ensanchamiento seguido de una conversión unboxing, a continuación, seguido por una conversión primitiva ensanchamiento
  • una conversión de boxeo (§5.1.7)
  • una conversión de boxeo seguido por una conversión de referencia ensanchamiento
  • una conversión unboxing (§5.1.8)
  • una conversión unboxing seguido por una conversión primitiva ensanchamiento ".

Para ir de 'a'a Integer, tendríamos que 1 ensanchar el charvalor a una intcontinuación de la caja inta una Integer. Pero si nos fijamos en las combinaciones de las conversiones que se permiten, no se puede hacer una conversión primitiva ensanchamiento seguido de una conversión de boxeo.

Por lo tanto, 'a'a Integerque no está permitido. Esto explica el error de compilación en el primer caso.

Se podría pensar que 'a'al Byteno está permitida ya que se incurriría una conversión de restricción primitiva ... que no está en la lista en absoluto. De hecho, los literales son un caso especial. JLS 5.2 va a decir lo siguiente.

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

  • Una conversión primitiva estrechamiento puede ser utilizado si la variable es de tipo byte, short, o char, y el valor de la expresión de la constante es representable en el tipo de la variable.

  • Una conversión primitiva estrechamiento seguido de una conversión de boxeo se puede usar si la variable es de tipo Byte, Shorto Character, y el valor de la expresión de la constante es representable en el byte de tipo, corto, o CHAR respectivamente ".

El segundo de ellos se aplica a 'a'que Byte, debido a que:

  • un literal de caracteres es una expresión constante, y
  • el valor de 'a'es 97decimal, que está dentro del rango para byte( -128a +127).

Esto explica por qué no hay error de compilación en el segundo ejemplo.


1 - No podemos boxear 'a'a una Charactery luego ampliar Charactera Integerporque Characterno es un subtipo de Java Integer. Sólo se puede utilizar una conversión de referencia cada vez mayor si el tipo de fuente es un subtipo del tipo de destino.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=309688&siteId=1
Recomendado
Clasificación