Truques bobos em Java (2)

GOTO

Oficialmente, Java não tem goto. A palavra é até reservada, mas só para poder dar erro mesmo…

A alternativa dada são break e continue rotulados. Eu achava que só era possível rotular loops (afinal, break e continue são usados em loops), mas lendo a especificação (o truque da postagem anterior eu também descobri lendo a especificação) percebi que qualquer statement pode ser rotulado, transformando break praticamente em “goto pra frente”! Edit: O continue bem que poderia ser um “goto pra trás” mas na verdade dá um erro (ver comentários deste post). É possível transformar o continue num goto para trás criando um loop “só para satisfazer o compilador” assim: label: for(;;){ <...código...> if(condição) continue label; <...código...> break label; } mas aí seria muita gambiarra. Fiquemos então com o break apenas, já que a idéia era mostrar um recurso normal da linguagem mas pouco usado.

Por exemplo, se quisermos procurar por caracteres inválidos numa String e fazer um escape nela, sem precisar alocar uma nova String caso a original já seja válida, podemos fazer um loop para testar toda a String e outro para fazer o escape apenas se o primeiro sair com break.

checkString: {
     for(...) {
         if(...) break checkString;
     }
     return originalString; // checked the whole String, no problem found
}
// invalid character found, escape it and return a new String
StringBuilder builder = new StringBuilder(originalString.length() + EXTRA_BUFFER);
for(...) {
    ...
}
return builder.toString();

Outras maneiras de fazer seriam: repetir o teste fora do for para descobrir se saiu normalmente ou com break, quebrar a lógica em funções menores, colocar todo o código de escape dentro do if que faz o break (se for só um), ou simplesmente cortar fora metade do código e montar uma nova String sempre, mesmo que não haja nenhum caracter inválido. Todas são soluções aceitáveis, mas numa biblioteca eu esperaria a implementação mais eficiente, sem cópias desnecessárias.

Anúncios

4 pensamentos sobre “Truques bobos em Java (2)

  1. Whoa, que viaaagem! Mas aqui só funcionou com o break; o continue ele reclama que “not a loop label” (Java 6 aqui)…

    (De brinde ainda descobri que “unreachable statement” é um *erro* em Java, não warning…)

    • Bah, pra dizer a verdade, não testei com continue, só com break! (posts em blogs são que nem software: o que a gente não testa é onde dá erro, mesmo quando é a coisa mais simples do mundo — ou melhor, o que a gente testa também dá erro, só que um pouco menos…)

      Sim, unreachable statement é um erro e não warning em Java. Mas tudo bem. Li num blog que na linguagem Go “import não usado” é um erro e não warning… Parece que os criadores da linguagem estavam irritados com projetos enormes onde não sabiam mais quais libs eram realmente usadas, hehehe.

      Enquanto isso, vou escrevendo if(true) return; para evitar o erro de unreachable statement.

      • Hmm, boa essa do “if (true) return;”. Se eu precisar programar em Java algum dia (espero que nunca) isso pode ser útil. :P Eu lembro de já ter feito mais de uma vez em C de colocar um “return;” no começo de uma função para “comentar” ela fora para fazer testes. Mas como eu já comentei antes, Java não foi projetado para rodar programas incompletos.

        (Por outro lado, se o SBCL encontra uma referência a uma variável não definida ele emite um warning e assume que a variável é global. Afinal, vai que o usuário define ela no REPL depois, né… :P)

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s