Me parece que la clase booleana es un candidato ideal para implementarse como una enumeración.
Mirando el código fuente, la mayoría de la clase son métodos estáticos que podrían moverse sin cambios a una enumeración, el resto se vuelve mucho más simple como una enumeración. Comparar original (comentarios y métodos estáticos eliminados):
public final class Boolean implements java.io.Serializable,
Comparable<Boolean>
{
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
private final boolean value;
public Boolean(boolean value) {
this.value = value;
}
public Boolean(String s) {
this(toBoolean(s));
}
public boolean booleanValue() {
return value;
}
public String toString() {
return value ? "true" : "false";
}
public int hashCode() {
return value ? 1231 : 1237;
}
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
public int compareTo(Boolean b) {
return compare(this.value, b.value);
}
}
con una versión enum:
public enum Boolean implements Comparable<Boolean>
{
FALSE(false), TRUE(true);
private Boolean(boolean value) {
this.value = value;
}
private final boolean value;
public boolean booleanValue() {
return value;
}
public String toString() {
return value ? "true" : "false";
}
}
¿Hay alguna razón por la que Boolean no pueda convertirse en una enumeración?
Si este es el código de Sun para anular el método equals (), le falta una comprobación fundamental de comparar las referencias de los dos objetos antes de comparar sus valores. Así es como creo que debería ser el método equals ():
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
java
api
source-code
Highland Mark
fuente
fuente
if
) pero desde un punto de vista de teoría conceptual / tipo, los booleanos y las enumeraciones son instancias de tipos de suma, por lo que creo que es justo preguntar por qué no lo hicieron. No cerrar la brecha entre ellos.valueOf(String)
(lo que entraría en conflicto con el valor de la enumeración de) y la magia detrás de lagetBoolean
cual puede hacer queBoolean.valueOf("yes")
devuelva verdadero en lugar de falso. Ambos son parte de la especificación 1.0 y necesitarían una compatibilidad con versiones anteriores adecuada.Respuestas:
Bueno, supongo que podría comenzar argumentando que las enumeraciones de Java no se agregaron al lenguaje de programación Java hasta el JDK 1.5. y, por lo tanto, esta solución ni siquiera era una alternativa en los primeros días cuando se definió la clase booleana.
Dicho esto, Java tiene la reputación de mantener la compatibilidad con versiones anteriores entre versiones y, por lo tanto, incluso si hoy consideramos su solución como una buena alternativa, no podemos hacerlo sin romper miles de líneas de código que ya usan el viejo Boolean. clase.
fuente
new Boolean("True")
ynew Boolean("true")
también puede causar algunos problemas con la implementación hipotética de enumeración.Hay algunas cosas que no funcionan, y no funcionan de manera bastante sorprendente cuando se comparan con la funcionalidad anterior del booleano de Java.
Vamos a ignorar el boxeo ya que eso fue algo agregado con 1.5. Hipotéticamente, si Sun quisiera, podrían haber hecho
enum Boolean
que se comportara como el boxeo realizado en elclass Boolean
.Sin embargo, hay otras formas sorprendentes (para el codificador) de que esto se rompería repentinamente en comparación con la funcionalidad de la clase anterior.
El problema valueOf (String)
Un ejemplo simple de esto es:
La ejecución de este código da:
El problema aquí es que no puedo pasar por todo lo que no es
TRUE
oFALSE
quevalueOf(String)
.Eso está bien ... simplemente lo anularemos con nuestro propio método ...
Pero ... hay un problema aquí. No puede anular un método estático .
Y así, todo el código que está pasando alrededor de
true
oTrue
o algún otro caso se mezclan error - y de manera espectacular con una excepción de tiempo de ejecución.Un poco más de diversión con valor
Hay otros bits que no funcionan muy bien:
Para
foo
, solo recibo una advertencia sobre el boxeo de un valor ya encuadrado. Sin embargo, el código para la barra es un error de sintaxis:Si coercimos ese error de sintaxis nuevamente en un
String
tipo:Recuperamos nuestro error de tiempo de ejecución:
¿Por qué alguien escribiría eso? No sé ... pero su código solía funcionar y ya no funcionaría.
No me malinterpreten, realmente me gusta la idea de una sola copia de un objeto inmutable dado. La enumeración resuelve este problema. Personalmente, he encontrado código de proveedor que tenía errores del código de proveedor que se parecía a esto:
eso nunca funcionó (No, no lo arreglé porque el estado incorrecto se solucionó en otro lugar, y arreglarlo lo rompió de maneras extrañas que realmente no tuve tiempo para depurar) . Si esto fuera una enumeración, ese código habría funcionado en su lugar.
Sin embargo, las necesidades de la sintaxis alrededor de la enumeración ( distingue entre mayúsculas y minúsculas, profundice en el directorio enumConstantDirectory
valueOf
, errores de tiempo de ejecución que deben funcionar de esa manera para las otras enumeraciones) y la forma en que funcionan los métodos estáticos hace que se rompan varias cosas que impiden siendo una caída en reemplazo de un booleano.fuente
of
ofrom
un javadoc apropiado.valueOf
y Boolean.valueOf () ha estado allí desde 1.0 . O Enums no podría usar valueOf como método estático, o Boolean necesitaría un método diferente al que ha estado usando. Hacer cualquiera rompe la convención o la compatibilidad, y no hacer que Boolean sea una enumeración tampoco. A partir de esto, la elección es bastante simple.Boolean.valueOf(Boolean.valueOf("TRUE"))
, hay dosvalueOf
métodos diferentes :valueOf(String)
yvalueOf(boolean)
. El error de sintaxis se debe a que olvidó implementar elvalueOf(boolean)
inMyBoolean
. Luego está el autounboxing entre las dos llamadas, que está codificado en el idiomaBoolean
pero noMyBoolean
. Si implementóvalueOf(boolean)
MyBoolean.valueOf(MyBoolean.valueOf("FALSE").booleanValue())
trabajosLo más probable es que el
boolean
tipo primitivo no sea unEnum
, y las versiones en caja de los tipos primitivos se comporten de manera casi idéntica a su versión sin caja. P.ej(El rendimiento puede no ser el mismo, pero ese es un tema diferente).
Sería extraño si pudieras escribir:
pero no:
fuente
if
trabajo tal como lo hace actualmente. Por otro lado, no hay forma de ignorar el hecho de que ha agregado una funcionalidad adicional a laBoolean
queboolean
no tiene.Además del
valueOf
problema (que es un problema en el nivel Java, podría funcionar bien en el nivel JVM), es porqueBoolean
tiene un constructor público. Esa fue una mala idea, actualmente en desuso, pero está aquí para quedarse.fuente
La razón es que "bool" era parte del lenguaje Java mucho antes que "enum". Durante muchos años, "bool" fue muy deseable, mientras que "enum" no estaba disponible. Solo que ahora puede decir "si enum hubiera estado disponible desde el principio, entonces podríamos haber implementado bool como una enumeración en lugar de un tipo separado".
En Swift, que podría haber expresado "bool" como una enumeración, hay tres estructuras llamadas "Bool", "DarwinBoolean" y "ObjCBool" que implementan el protocolo "ExpressibleByBooleanLiteral". (DarwinBoolean es compatible con un bool de C o C ++, ObjCBool es compatible con un BOOL de Objective-C). "verdadero" y "falso" son valores especiales reconocidos por el compilador, y solo pueden usarse para inicializar objetos que admitan el protocolo "ExpressibleByBooleanLiteral". Bool tiene una variable interna "_value" que contiene un entero de un bit.
Entonces Bool no es parte del lenguaje Swift, sino de la biblioteca estándar. verdadero y falso son parte del lenguaje, y también lo es el protocolo ExpressibleByBooleanLiteral.
fuente