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). 🙂

5 Replies to “Recurso inútil do Java”

  1. Parcularmente nao penso com você!

    “Pra que reinvetar a roda”
    Todos sabem q C++ vem C ou seja, C apanhou muito em sua vida e todos sabem q apanhou muito por causa dos Ponteiros! Crio que pensaram +/- assim: “Vamos amadurecer o C” é como um pessoa morresse e levasse tudo com ela!

    “Como o sistema octal raramente tem utilidade prática na computação”
    Na verdade se voce vivesse no mundo da robotica nunca voce iria dizer isso

    “no máximo é usado ao definir permissões de arquivo em Unix/Linux (chmod)”
    Os numeros de permisao em arquivos de sistema Unix sao numeros binarios passado para decimal (tem nada de octal)
    se nao me engano era algo assim:
    1 – Ler
    1 – Escrever
    1 – Executar

    em binario seria 111 passando para decimal (pode usar a calculadora do windows para testar) é 7 por isso q eh comum ver chmod 777
    q eh

    A,G,R
    1,1,1 – Ler
    1,1,1 – Escrever
    1,1,1 – Executar

    (A-Arquivo, G-Grupo, R-Resto)

  2. Raphael: Muito obrigado pelo comentário! Participação, críticas e sugestões assim são sempre bem-vindas, enriquecem a discussão dos temas. Gostaria de responder pontos do seu comentário (#1).

    “para que reinventar a roda”
    – Na verdade, eu só quis lembrar que a sintaxe da linguagem Java foi inspirada na de C/C++, ao invés de “reinventar a roda” definindo uma sintaxe completamente nova. Fora a sintaxe similar, não há dúvida de que são diversas as diferenças conceituais e estruturais entre Java e C++ e mesmo entre C e C++. O assunto é extenso e não é foco deste artigo (Veja http://www.cprogramming.com/tutorial/java/syntax-differences-java-c++.html e outros). Meu ponto central, para introduzir o artigo, é simplesmente que foi da sintaxe inspirada em C/C++ que surgiram os literais octais em Java.
    Ponderando sobre isto, revisei o artigo e retirei a observação que eu havia originalmente colocado “(para quê reinventar a roda, certo?)”.

    “Na verdade se voce vivesse no mundo da robotica nunca voce iria dizer isso”
    – Obrigado pela informação. Concordo que, quando eu disse que octal raramente tem utilidade, soou meio exagerado. Revisei agora o artigo, mudando para:
    “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”
    – Contudo, você há de concordar que mesmo com uso em robótica e um ou outro campo de aplicação específico, está longe de podermos chamar o sistema octal de um recurso de uso amplo, geral e comum na linguagem.

    “Os numeros de permisao em arquivos de sistema Unix sao numeros binarios passado para decimal (tem nada de octal)”
    – Binário, octal, hexadecimal, decimal etc., são apenas sistemas numéricos (base 2, 8, 16, 10 etc.) para se representar números ou valores. Um mesmo inteiro pode ser representado em qualquer base numérica. Apenas certas representações são mais ou menos adequadas para determinadas aplicações ou contextos.
    – As permissões no sistema de arquivos de Unix/Linux são divididas em três agrupamentos principais — dono, grupo, outros — (e mais um especial), cada agrupamento destes com três bits. Cada bit corresponde, como você mesmo citou, às respectivas permissões de leitura, escrita e execução. Os possíveis estados distintos de cada um destes grupos de três bits são oito (valores de 000 = 0 a 111 = 7). Portanto, os grupos de permissão no Unix são um cenário adequado para representação como dígitos octais (de 0 a 7). Mas os mesmos bits podem ser escritos em qualquer outra base numérica.
    Exemplo: 777 octal = 111111111 binário = 1FF hexa = 511 decimal.

  3. “O assunto é extenso e não é foco deste artigo”

    ehehe realmente, mas acho q isso foi uma jogada de markting para pegar todo mundo q programava em C/C++

    E novamente afirmo
    “Os numeros de permisao em arquivos de sistema Unix sao numeros binarios passado para decimal (tem nada de octal)”

    Digo isso porque essa é uma teqnica usada chamada de Bitflag, vamos supor que alem de Ler, Escrever e Executar teriamos Atualizar ae seria

    ler=1
    escrever=1
    executar=1
    atualizar=1

    ae alende da permissao total que seria 777 seria 15 15 15
    se fosse em octal seria 17 17 17

  4. Rafael: Sim, as permissões de arquivo do Unix File System (UFS) — também chamadas de modo — são armazenadas no inode em um registrador que representa um conjunto de bits de flag. Por isso, estes flags são chamados mode bits do inode, ou i_mode na estrutura física.

    O fato principal é que, no UFS tradicional, estes flags são considerados em conjuntos de três bits (corespondendo aos flags de ler, escrever e executar — rwx). É portanto comum e intuitivo representar cada agrupamento de três bits de permissão como um algarismo octal. O próprio comando chmod aceita a sintaxe de permissões em octal. Resumo: O sistema octal é uma forma usual de se representar ou referenciar os agrupamentos de três bits (flags) de permissões do UFS.

    Nota: Sistemas de arquivo mais avançados provêem mais tipos de permissão — no Andrew File System (AFS), por exemplo, são 7 ao invés das 3 do UFS — e usam estruturas de ACL (access control list), ao invés dos bitflags.

    Algumas referências:
    http://www.tux4u.nl/freedocs/unix/draw/inode.pdf
    http://en.wikipedia.org/wiki/Chmod#Octal_numbers
    http://en.wikipedia.org/wiki/File_system_permissions#Octal_notation
    http://www.cs.indiana.edu/csg/help/permissions.html
    http://fxr.watson.org/fxr/source/include/linux/fs.h?v=linux-2.4.22#L438
    http://afs.caspur.it/afs/italia/project/afs/docs/AFS-3.6-UNIX/AdminGd/auagd020.htm#HDRWQ781
    http://www.angelfire.com/hi/plutonic/afs-faq.html#sub2.01

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *