As instruções de alternância com Stringcasos foram implementadas no Java SE 7 , pelo menos 16 anos após a primeira solicitação. Um motivo claro para o atraso não foi fornecido, mas provavelmente tinha a ver com desempenho.
Implementação no JDK 7
O recurso agora foi implementado javac com um processo de "remoção de açúcar"; uma sintaxe limpa e de alto nível usando Stringconstantes nas casedeclarações é expandida no tempo de compilação para um código mais complexo, seguindo um padrão. O código resultante usa instruções da JVM que sempre existiram.
A switchcom Stringcasos é convertido em dois comutadores durante a compilação. A primeira mapeia cada sequência para um número inteiro único - sua posição no comutador original. Isso é feito ativando primeiro o código de hash do rótulo. O caso correspondente é uma ifinstrução que testa a igualdade das cadeias de caracteres; se houver colisões no hash, o teste será em cascata if-else-if. A segunda opção espelha isso no código-fonte original, mas substitui os rótulos das caixas pelas suas posições correspondentes. Esse processo de duas etapas facilita a preservação do controle de fluxo da chave original.
Comutadores na JVM
Para obter mais detalhes técnicos switch, consulte a Especificação da JVM, na qual a compilação das instruções do switch é descrita. Em poucas palavras, existem duas instruções diferentes da JVM que podem ser usadas para um comutador, dependendo da escassez das constantes usadas pelos casos. Ambos dependem do uso de constantes inteiras para que cada caso seja executado com eficiência.
Se as constantes são densas, elas são usadas como um índice (após subtrair o valor mais baixo) em uma tabela de indicadores de instruções - a tableswitchinstrução.
Se as constantes forem escassas, uma pesquisa binária do caso correto é executada - a lookupswitchinstrução.
Em de-adoçamento um switchem Stringobjetos, ambas as instruções são susceptíveis de ser utilizados. A lookupswitché apropriado para o primeiro comutador de códigos de hash para encontrar a posição original do caso. O ordinal resultante é um ajuste natural para a tableswitch.
Ambas as instruções exigem que as constantes inteiras atribuídas a cada caso sejam classificadas em tempo de compilação. Em tempo de execução, embora o O(1)desempenho de tableswitchgeralmente pareça melhor que o O(log(n))desempenho de lookupswitch, ele requer alguma análise para determinar se a tabela é densa o suficiente para justificar a troca espaço-tempo. Bill Venners escreveu um ótimo artigo que aborda isso com mais detalhes, juntamente com uma análise detalhada de outras instruções de controle de fluxo Java.
Antes do JDK 7
Antes do JDK 7, enumera possível aproximar um Stringcomutador baseado em. Isso usa ovalueOf método estático gerado pelo compilador em todos os enumtipos. Por exemplo:
Pill p = Pill.valueOf(str);
switch(p) {
case RED: pop(); break;
case BLUE: push(); break;
}