Eu só estou querendo saber por que a switch
instrução Java 7 não suporta um null
caso e, em vez disso, lança NullPointerException
? Veja a linha comentada abaixo (exemplo extraído do artigo Java Tutorialsswitch
):
{
String month = null;
switch (month) {
case "january":
monthNumber = 1;
break;
case "february":
monthNumber = 2;
break;
case "march":
monthNumber = 3;
break;
//case null:
default:
monthNumber = 0;
break;
}
return monthNumber;
}
Isso evitaria uma if
condição para verificação nula antes de cada switch
uso.
java
switch-statement
language-design
Prashant Bhate
fonte
fonte
null
causará uma exceção. Faça umaif
verificaçãonull
e entre naswitch
instrução.NullPointerException
se a expressão é avaliadanull
em tempo de execução] é um resultado melhor do que ignorar silenciosamente toda a instrução switch ou optar por executar as instruções (se houver) após o etiqueta padrão (se houver).Respostas:
Como damryfbfnetsi aponta nos comentários, o JLS §14.11 tem a seguinte nota:
(ênfase minha)
Embora a última frase ignore a possibilidade de uso
case null:
, ela parece razoável e oferece uma visão das intenções dos designers de linguagem.Se preferirmos examinar os detalhes da implementação, esta postagem de blog de Christian Hujer tem algumas especulações esclarecedoras sobre por que
null
não é permitido em comutadores (embora esteja centrado noenum
comutador e não noString
comutador):Enquanto os
String
comutadores são implementados de maneira diferente , oenum
comutador veio primeiro e definiu o precedente de como a ativação de um tipo de referência deve se comportar quando a referência énull
.fonte
case null:
se tivesse sido implementado exclusivamente paraString
. Atualmente, todaString
verificação requer uma verificação nula de qualquer maneira, se queremos fazê-lo corretamente, embora principalmente implicitamente, colocando a string constante primeiro como em"123test".equals(value)
. Agora somos forçados a escrever nossa declaração de switch como emif (value != null) switch (value) {...
Em geral,
null
é desagradável de manusear; talvez um idioma melhor possa viver semnull
.Seu problema pode ser resolvido por
fonte
month
for uma string vazia: isso a tratará da mesma maneira que uma string nula.Não é bonito, mas
String.valueOf()
permite que você use uma String nula em um switch. Se encontrarnull
, ele será convertido em"null"
, caso contrário, ele retornará a mesma String que você passou. Se você não manipular"null"
explicitamente, ele irá paradefault
. A única ressalva é que não há como distinguir entre a String"null"
e umanull
variável real .fonte
Esta é uma tentativa de responder por que lança
NullPointerException
A saída do comando javap abaixo revela que
case
é escolhido com base no código de hash daswitch
sequência de argumentos e, portanto, lança o NPE quando.hashCode()
é invocado na sequência nula.Isso significa que, com base nas respostas do hashCode do Java, é possível produzir o mesmo valor para diferentes strings? , embora raro, ainda existe a possibilidade de dois casos serem correspondidos (duas cadeias com o mesmo código de hash). Veja este exemplo abaixo
javap para o qual
Como você pode ver, apenas um caso é gerado para
"Ea"
e"FB"
com duasif
condições para verificar uma correspondência com cada sequência de casos. Maneira muito interessante e complicada de implementar essa funcionalidade!fonte
hashCode
retorno dos mesmos valores em diferentes execuções de um programa, mas desde que os hashes da string sejam inseridos nos executáveis por o compilador, o método hash da string acaba fazendo parte das especificações da linguagem.Longa história curta ... (e espero que interessante o suficiente !!!)
O enum foi introduzido pela primeira vez no Java1.5 ( Sep'2004 ) e o bug que solicitava a ativação da String foi arquivado há muito tempo ( Out'95 ). Se você olhar para o comentário publicado sobre esse bug em junho de 2004 ,
Don't hold your breath. Nothing resembling this is in our plans.
parece que eles adiaram ( ignoraram ) esse bug e finalmente lançaram o Java 1.5 no mesmo ano em que eles introduziram 'enum' com ordinal começando em 0 e decidiram ( perdeu ) não apoiar nulo para enum. Mais tarde, em Java1.7 ( Jul'2011 ), eles seguiram ( forçado) a mesma filosofia com String (ou seja, ao gerar o bytecode, nenhuma verificação nula foi executada antes de chamar o método hashcode ()).Então eu acho que tudo se resume ao fato de o enum ter entrado primeiro e ter sido implementado com seu início ordinal em 0 devido ao qual eles não podiam suportar valor nulo no bloco de comutador e, mais tarde, com String, eles decidiram forçar a mesma filosofia, ou seja, valor nulo não permitido no bloco do interruptor.
TL; DR Com String, eles poderiam cuidar do NPE (causado pela tentativa de gerar código hash para nulo) enquanto implementavam código java em conversão de código de bytes, mas finalmente decidiram não.
Ref: TheBUG , JavaVersionHistory , JavaCodeToByteCode , SO
fonte
De acordo com o Java Docs:
Como
null
não tem tipo e não é uma instância de nada, não funcionará com uma instrução switch.fonte
null
é um valor válido para umString
,Character
,Byte
,Short
, ouInteger
de referência.A resposta é simplesmente que, se você usar um comutador com um tipo de referência (como um tipo primitivo in a box), o erro em tempo de execução ocorrerá se a expressão for nula, pois, ao descompactar, ele lançaria o NPE.
portanto, caso nulo (que é ilegal) nunca poderia ser executado de qualquer maneira;)
fonte
if (x == null) { // the case: null part }
Concordo com comentários perspicazes (sob o capô ....) em https://stackoverflow.com/a/18263594/1053496 na resposta de @Paul Bellora.
Encontrei mais um motivo da minha experiência.
Se 'case' puder ser nulo, o que significa que switch (variável) é nulo, desde que o desenvolvedor forneça um caso 'null' correspondente, podemos argumentar que está tudo bem. Mas o que acontecerá se o desenvolvedor não fornecer nenhum caso 'nulo' correspondente. Em seguida, temos que correspondê-lo a um caso 'padrão', que pode não ser o que o desenvolvedor pretendeu tratar no caso padrão. Portanto, combinar 'nulo' com um padrão pode causar 'comportamento surpreendente'. Portanto, jogar 'NPE' fará com que o desenvolvedor lide com todos os casos explicitamente. Eu achei jogando NPE nesse caso muito atencioso.
fonte
Use a classe Apache StringUtils
fonte