Parece-me que a classe booleana é um candidato ideal para ser implementado como um enum.
Observando o código-fonte, a maioria da classe são métodos estáticos que podem ser movidos inalterados para um enum, o restante se torna muito mais simples como um enum. Compare o original (comentários e métodos estáticos removidos):
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);
}
}
com uma versão 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";
}
}
Existe alguma razão pela qual o booleano não pode se tornar um enum?
Se este é o código Sun para substituir o método equals (), está faltando uma verificação muito fundamental na comparação das referências dos dois objetos antes de comparar seus valores. É assim que eu acho que o método equals () deve ser:
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
fonte
fonte
if
), mas do ponto de vista da teoria conceitual / de tipo booleanos e enums são instâncias de tipos de soma, por isso acho justo perguntar por que eles não não preenche a lacuna entre eles.valueOf(String)
(que entraria em conflito com o valor da enumeração) e a mágica por trás dagetBoolean
qual ela pode fazer com queBoolean.valueOf("yes")
retorne verdadeiro e não falso. Ambos fazem parte da especificação 1.0 e precisariam de compatibilidade com versões anteriores.Respostas:
Bem, acho que poderia começar argumentando que as enumerações Java não foram adicionadas à linguagem de programação Java até o JDK 1.5. e, portanto, essa solução não era sequer uma alternativa nos primeiros dias em que a classe booleana foi definida.
Dito isso, o Java tem a reputação de manter a compatibilidade com versões anteriores entre versões e, portanto, mesmo que hoje consideremos sua solução como uma boa alternativa, não podemos fazê-lo sem quebrar milhares de linhas de código por aí já usando o antigo booleano classe.
fonte
new Boolean("True")
enew Boolean("true")
também pode causar alguns problemas com a implementação do enum hipotético.Existem algumas coisas que não funcionam e não funcionam de maneiras surpreendentes quando você as compara à funcionalidade anterior do booleano de Java.
Vamos ignorar o boxe, pois isso foi algo adicionado ao 1.5. Hipoteticamente, se a Sun quisesse, eles poderiam ter
enum Boolean
se comportado exatamente como o boxe realizado noclass Boolean
.No entanto, existem outras maneiras surpreendentes (para o codificador) de que isso seria interrompido repentinamente em comparação com a funcionalidade da classe anterior.
O problema valueOf (String)
Um exemplo simples disso é:
A execução deste código fornece:
O problema aqui é que eu não posso passar por qualquer coisa que não é
TRUE
, ouFALSE
paravalueOf(String)
.Tudo bem ... vamos substituí-lo por nosso próprio método ...
Mas ... há um problema aqui. Você não pode substituir um método estático .
E assim, todo o código que está passando em torno
true
ouTrue
ou algum outro caso misturado vai erro fora - e bastante espetacular com uma exceção de tempo de execução.Um pouco mais divertido com valor
Existem outros bits que não funcionam muito bem:
Pois
foo
, recebo apenas um aviso sobre o boxe com um valor já em caixa. No entanto, o código para bar é um erro de sintaxe:Se forçarmos esse erro de sintaxe de volta a um
String
tipo:Recuperamos o erro de tempo de execução:
Por que alguém escreveria isso? Não sei ... mas seu código costumava funcionar e não funcionava mais.
Não me interpretem mal, eu realmente gosto da ideia de apenas uma cópia de um determinado objeto imutável de todos os tempos. O enum resolve esse problema. Eu, pessoalmente, encontrei o código do fornecedor que apresentava bugs no código do fornecedor que se parecia com isso:
isso nunca funcionou (não, eu não o consertei porque o estado incorreto foi consertado em outro lugar, e consertar isso quebrou isso de maneiras estranhas que eu realmente não tive tempo para depurar) . Se isso fosse um enum, esse código teria funcionado.
No entanto, as necessidades da sintaxe em torno da enum ( diferencia maiúsculas de minúsculas - investigam o enumConstantDirectory por trás
valueOf
, erros de tempo de execução que precisam funcionar dessa maneira para as outras enumerações) e a maneira como os métodos estáticos funcionam causa uma quebra de várias coisas que o impedem de sendo uma queda em substituição a um booleano.fonte
of
oufrom
o javadoc apropriado.valueOf
e Boolean.valueOf () existe desde 1.0 . Ou o Enums não seria capaz de usar valueOf como um método estático ou o Boolean precisaria de um método diferente daquele que está usando. Fazer quebra de convenção ou compatibilidade - e não ter um booleano como enum também não quebra. A partir disso, a escolha é bastante simples.Boolean.valueOf(Boolean.valueOf("TRUE"))
, existem doisvalueOf
métodos diferentes :valueOf(String)
evalueOf(boolean)
. O erro de sintaxe é porque você esqueceu de implementar ovalueOf(boolean)
inMyBoolean
. Depois, há o autounboxing entre as duas chamadas, que é codificado na língua paraBoolean
, mas nãoMyBoolean
.Se você implementouvalueOf(boolean)
MyBoolean.valueOf(MyBoolean.valueOf("FALSE").booleanValue())
obrasProvavelmente porque o
boolean
tipo primitivo não é umEnum
e as versões em caixa dos tipos primitivos se comportam quase de forma idêntica à sua versão não em caixa. Por exemplo(O desempenho pode não ser o mesmo, mas esse é um assunto diferente.)
Seria meio estranho se você pudesse escrever:
mas não:
fonte
if
trabalho exatamente como ele faz atualmente. Por outro lado, não há como ignorar o fato de que você adicionou funcionalidades extras àsBoolean
queboolean
não possuem.Além da
valueOf
questão (que é uma questão no nível Java, pode funcionar bem no nível da JVM), é porqueBoolean
possui um construtor público. Essa foi uma péssima idéia, atualmente descontinuada, mas chegou para ficar.fonte
O motivo é que "bool" fazia parte da linguagem Java muito antes do "enum". Por muitos anos, "bool" era muito desejável, enquanto "enum" não estava disponível. Somente agora você pode dizer "se o enum estivesse disponível desde o início, poderíamos ter implementado o bool como um enum em vez de um tipo separado".
No Swift, que poderia expressar "bool" como uma enumeração, existem três estruturas denominadas "Bool", "DarwinBoolean" e "ObjCBool" implementando o protocolo "ExpressibleByBooleanLiteral". (DarwinBoolean é compatível com um booleano C ou C ++, ObjCBool é compatível com um BOOL Objective-C). "true" e "false" são valores especiais reconhecidos pelo compilador e só podem ser usados para inicializar objetos que suportam o protocolo "ExpressibleByBooleanLiteral". Bool possui uma variável interna "_value" que contém um número inteiro de um bit.
Portanto, o Bool não faz parte da linguagem Swift, mas da biblioteca padrão. true e false fazem parte do idioma, assim como o protocolo ExpressibleByBooleanLiteral.
fonte