Recurso inútil do Java

Java se inspirou na sintaxe do C/C++, deixando de fora algumas características perigosas como a manipulação direta de ponteiros ou o uso de valores inteiros para representar estados lógicos (0 = falso, não zero = verdadeiro).

Mas pelo menos um recurso de sintaxe herdado do C/C++ é tão inútil quanto perigoso. Antes de citar, vou exemplificar o perigo. Diga qual é o resultado impresso pelo comando Java a seguir:

System.out.println(123 - 012);

Se você respondeu 111, caiu na armadilha. O correto é 113.

Por que? Todo literal inteiro começado por 0 é interpretado como um valor no sistema octal (JLS 3.10.1), isto é, um número inteiro na base 8.

Assim, 012 em Java (e C) não é interpretado como um número decimal, mas sim octal. 012 Na base 8 (octal) equivale a 10 na base 10 (decimal): 1 × 81 + 2 × 80 = 8 + 2 = 10. Logo, 123 – 10 = 113. 🙁

Como o sistema octal tem uso pouco comum na computação em geral — lembro-me apenas de seu uso freqüente ao definir permissões de arquivo em Unix/Linux (chmod) –, o tratamento de inteiro octal em Java me parece um recurso de raro uso, mas fonte fácil de enganos, como no exemplo acima.

O risco do tratamento automático de inteiros iniciados por zero como octal não é só em literais no código fonte. Pode ocorrer também na interpretação (conversão) de texto como inteiro, como no exemplo a seguir: Integer.parseInt("012");

Para evitar este problema no método parseInt(), use o método sobrecarregado onde um segundo parâmetro explicita a base numérica decimal:

Integer.parseInt(stringVal, 10);

A lição sobre este recurso é resumida no tópico 59 do interessante livro Java Puzzlers (Bloch & Gafter, 2005, ISBN 0-321-33678-X): nunca preencha zeros à esquerda em um literal inteiro (a menos que você saiba exatamente o que está fazendo). 🙂