Veo que la sintaxis de conversión explícita para booleano (boolean)
es sintácticamente legal, pero no puedo pensar en un uso para ello. El objeto booleano correspondiente (o, más bien, alternar entre booleano y booleano) se maneja mediante autoboxing. Entonces parece un artefacto de lenguaje inútil del compilador. ¿Hay un escenario funcional que me estoy perdiendo?
Puede marcar la diferencia cuando se llama a un método sobrecargado. Dado que el método a llamar está determinado por los tipos estáticos de los parámetros (consulte JLS, §15.12.2 ), convertir un Boolean
en un boolean
o viceversa puede cambiar el método que se llama:
class Ideone { public static void main (String[] args) { final Boolean b = true; foo((boolean) b); // prints out "primitive" foo(b); // prints out "wrapper" } public static void foo(boolean b) { System.out.println("primitive"); } public static void foo(Boolean b) { System.out.println("wrapper"); } }
Tenga en cuenta que cuando se convierte de Boolean
a boolean
, puede ocurrir una NullPointerException
cuando el Boolean
tiene un valor null
.
Sin embargo, si este comportamiento se usa (extensamente) o debería usarse es otro debate.
rzwitserloot mostró otro caso con boolean
y Object
en su respuesta . Si bien el caso de rzwisterloot parece similar, el mecanismo subyacente es diferente, ya que la conversión descendente de Object
a boolean
se define por separado en el JLS. Además, es propenso a una ClassCastException
(si el Object
no es Boolean
), así como a una NullPointerException
(si el Object
es null
).
No completamente.
Por lo general, aplicar el operador de conversión con un tipo primitivo solo tiene un propósito, que es convertir un tipo primitivo en otro. boolean
es el único tipo primitivo con la propiedad de que nada se puede convertir en booleano y un booleano no se puede convertir en nada más.
Pero, hay un segundo propósito para estos, aunque no está exactamente detallado en el JLS y es una práctica de estilo de código dudosa: efectivamente hace que se active el desempaquetado automático. E incluso combina el trabajo de activar el desempaquetado automático y un tipo de conversión ordinario:
Object o = true; boolean b = (boolean) o; o = "Hello"; b = (boolean) o;
compila muy bien. Provocará una ClassCastException en la cuarta línea, como se esperaba. Sin el elenco booleano, tendrías que hacer algo como:
boolean b = ((Boolean) o).booleanValue();
que es definitivamente más prolijo. Exactamente con qué frecuencia termina queriendo convertir alguna expresión de tipo Object
en boolean
; probablemente sea una ocurrencia muy rara, pero es real, y no permitir (boolean)
habría hecho que el JLS sea más largo, no más corto (y la base de código javac tampoco sería más corto).
Como se indicó en otras respuestas, puede usar un cambio a boolean
para hacer cumplir el desempaquetado automático o para seleccionar entre métodos sobrecargados. Como un caso especial, llamar a invokeExact
en MethodHandle
puede requerir una conversión de este tipo para seleccionar la firma de método correcta, incluso para el tipo de valor devuelto.
Pero hubo un tiempo en que ninguna de estas características existía, aún así, se permitió un lanzamiento boolean
. Agregar una regla especial para boolean
no simplificaría el lenguaje. Pero se habían considerado las implicaciones de permitir esta función.
Cuando analizamos la segunda edición de la especificación del lenguaje:
5.1.1 Conversiones de identidad
Se permite una conversión de un tipo a ese mismo tipo para cualquier tipo. Esto puede parecer trivial, pero tiene dos consecuencias prácticas. Primero, siempre se permite que una expresión tenga el tipo deseado para comenzar, lo que permite la regla simple de que cada expresión está sujeta a conversión, aunque solo sea una conversión de identidad trivial. En segundo lugar, implica que está permitido que un programa incluya operadores de conversión redundantes en aras de la claridad.
La única conversión permitida que implica el tipo booleano es la conversión de identidad de
boolean
aboolean
.
Entonces, en aquel entonces, un valor boolean
solo podía convertirse en boolean
, que incluso se declaró explícitamente, pero se permitió intencionalmente, por ejemplo, "en aras de la claridad".
Considere una llamada como foo(bar())
vs. foo((boolean)bar())
.
O, stringBuffer.append((boolean)someMethod())
.
El elenco no podía alterar el comportamiento del programa pero proporcionar información adicional al lector humano.
La versión actual aún establece que las conversiones de identidad están permitidas, pero no restringe las conversiones de boolean
a conversión de identidad, ya que ahora podemos convertir entre tipos boolean
y de referencia.
Incluso hay una segunda mención en la versión anterior:
15.16 Cast Expresiones
Una expresión de conversión convierte, en tiempo de ejecución, un valor de un tipo numérico en un valor similar de otro tipo numérico; o confirma, en tiempo de compilación, que el tipo de una expresión es booleano; o comprueba, en tiempo de ejecución, que un valor de referencia hace referencia a un objeto cuya clase es compatible con un tipo de referencia especificado.
Dado que las conversiones entre tipos primitivos y tipos de referencia no eran posibles en ese entonces, había tres casos de uso distintos para conversiones, conversiones numéricas, cambios de tipo de referencia o " confirma, en tiempo de compilación, que el tipo de una expresión es booleano ".
Como eso es lo único que podría hacer una boolean
en esa versión de Java.