java - linea - ¿Por qué el operador ternario lanza inesperadamente números enteros?
operador ternario java ejemplos (2)
Conversión numérica en el operador condicional? :
En el operador condicional a
?
b
:
c
, si tanto c
son tipos numéricos diferentes, las siguientes reglas de conversión se aplican en tiempo de compilación para hacer que sus tipos sean iguales , en orden:
Los tipos se convierten a sus primitivos correspondientes, lo que se denomina unboxing .
Si un operando era una constante
int
(noInteger
antes de unboxing) cuyo valor es representable en el otro tipo, elint
operando se convierte en el otro tipo.De lo contrario, el tipo más pequeño se convierte en el siguiente más grande hasta que ambos operandos tengan el mismo tipo. Las órdenes de conversión son:
byte
->short
->int
->long
->float
->double
char
->int
->long
->float
->double
Eventualmente, toda la expresión condicional obtiene el tipo de su segundo y tercer operandos.
Ejemplos:
Si combina char
con short
, la expresión se convierte en int
.
Si combina Integer
con Integer
, la expresión se convierte en Integer
.
Si combina final int i = 5
con un Character
, la expresión se convierte en char
.
Si combina short
con float
, la expresión se vuelve float
.
En el ejemplo de la pregunta, 200 se convierte de Integer
en double
, 0.0 se desempaqueta de Double
en double
y toda la expresión condicional se convierte en double
que finalmente se encapsula en Double
porque obj
es de tipo Object
.
Lo he visto discutido en alguna parte que el siguiente código da como resultado que obj
sea un Double
, pero que imprime 200.0
desde el lado izquierdo.
Object obj = true ? new Integer(200) : new Double(0.0);
System.out.println(obj);
Resultado: 200.0
Sin embargo, si coloca un objeto diferente en el lado derecho, p. Ej. BigDecimal
, el tipo de obj
es Integer
como debería ser.
Object obj = true ? new Integer(200) : new BigDecimal(0.0);
System.out.println(obj);
Resultado: 200
Supongo que la razón de esto tiene que ver con lanzar el lado izquierdo a un double
del mismo modo que ocurre para las comparaciones y cálculos integer
/ double
, pero aquí los lados izquierdo y derecho no interactúan de esta manera.
¿Por qué pasó esto?
Debe leer la sección 15.25 de la Especificación del lenguaje Java .
En particular:
De lo contrario, si el segundo y tercer operandos tienen tipos que son convertibles (§5.1.8) a tipos numéricos, entonces hay varios casos:
- Si uno de los operandos es de tipo byte o byte y el otro es de tipo short o short, entonces el tipo de expresión condicional es corto.
- Si uno de los operandos es de tipo T donde T es byte, short o char, y el otro operando es una expresión constante de tipo int cuyo valor es representable en tipo T, entonces> - el tipo de expresión condicional es T.
- Si uno de los operandos es de tipo Byte y el otro operando es una expresión constante de tipo int cuyo valor es representable en tipo byte, entonces el tipo de expresión condicional es byte.
- Si uno de los operandos es de tipo Short y el otro operando es una expresión constante de tipo int cuyo valor es representable en tipo short, entonces el tipo de expresión condicional es corto.
- Si uno de los operandos es de tipo; El carácter y el otro operando es una expresión constante de tipo int cuyo valor es representable en tipo char, luego el tipo de expresión condicional es char.
- De lo contrario, la promoción numérica binaria (§5.6.2) se aplica a los tipos de operandos, y el tipo de expresión condicional es el tipo promovido del segundo y tercer operandos. Tenga en cuenta que la promoción numérica binaria realiza la conversión de unboxing (§5.1.8) y la conversión de conjuntos de valores (§5.1.13).
Entonces se aplica la promoción numérica binaria , que comienza con:
Cuando un operador aplica la promoción numérica binaria a un par de operandos, cada uno de los cuales debe denotar un valor que es convertible a un tipo numérico, las siguientes reglas se aplican, en orden, usando conversión de ampliación (§5.1.2) para convertir operandos según sea necesario :
- Si alguno de los operandos es de un tipo de referencia, se realiza la conversión de unboxing (§5.1.8). Entonces:
- Si cualquiera de los dos operandos es del tipo double, el otro se convierte a double.
Eso es exactamente lo que sucede aquí: los tipos de parámetros se convierten a int
y double
respectivamente, el segundo operando (el tercero en la expresión original) es entonces de tipo double
, por lo que el tipo de resultado general es double
.