Curso de Java - Aula 3
Adicionado conteúdo para a terceira vídeo-aula do nosso Curso de Java. Agora você pode acompanhar o curso com este material de apoio e aprofundar-se ainda mais no estudo da linguagem de programação Java.
Introdução
Sejam bem vindos a mais uma aula do Curso de Java do Ponto G++. Nesta aula, inauguramos um novo bloco, o “Java Curiosa e Divertida”, onde iremos focalizar em cada aula algum aspecto curioso da linguagem de programação Java, que tenha alguma relação como os assuntos que estejam sendo estudados.
No bloco regular da aula, começamos enfatizando duas necessidades fundamentais: a rigorosa observância da sintaxe, que em Java pode ser às vezes bem complicada, e o uso de endentação para aumentar a clareza do código. Em seguida, fazemos uma brevíssima comparação da sintaxe de Java com a de outras linguagens de programação, e finalizamos apresentando as 50 palavras reservadas de uso interno da linguagem.
Desejo-lhes um bom aproveitamento do material desta aula.
Java Curiosa & Divertida
O Número Mágico do Bytecode
Antes de mais nada, para entender o que vamos tratar aqui, é preciso uma rápida revisão da representação dos números nas bases dois (binária), dez (decimal) e dezesseis (hexadecimal).
Observem as representações numéricas na figura abaixo:
Nela, podemos observar que um mesmo número pode ser representado por 47.531, na base decimal, por 1011100110101011, na base binária ou por B9AB, na base hexadecimal. De todas essas representações, a mais difícil para que nós, humanos, possamos entender é, sem dúvida alguma, a binária.
Inobstante o sistema decimal seja aquele com o qual estejamos mais habituados, ele não é o mais adequado para a identificação, por exemplo, dos endereços na memória dos computadores. Para isso é que foi adotado o sistema hexadecimal.
Os dígitos binários do exemplo acima, podem ser divididos em grupos de 4 bits, denominados nibbles, conforme pode ser observado na linha intermediária da figura, facilitando um pouco mais sua visualização. O mais importante contudo, além disso, é que cada grupo de 4 bits comporta exatamente 16 combinações diferentes (24) — e é aí que entram os números hexadecimais…
Mas como representar os 16 dígitos dessa base numérica? Simples: usamos os dez dígitos emprestados da base decimal (0 a 9) e completamos os demais com as seis primeiras letras do alfabeto — A, B, C, D, E e F. A correspondência com o sistema decimal seria, então, a seguinte:
A calculadora do Windows possui um modo programador (com equivalentes nos outros sistemas operacionais), que permite constatar visualmente a equivalência numérica nas três bases aqui examinadas, conforme observamos na figura abaixo:
A definição de “número mágico”, de acordo com a Wikipédia, é a seguinte:
Número mágico : um termo usado em informática para designar constantes especiais usadas para definir um certo propósito, usualmente escolhidas de forma arbitrária. Eles são chamados de mágicos pois a sua presença é inexplicável sem um conhecimento prévio do seu uso, seja informal com o criador da constante ou formal através de documentação.
No caso de Java, a identificação do bytecode, ou seja, o arquivo compilado .class
, é um cabeçalho de 4 bytes: CA FE BA BE, em hexadecimal. Quem nos conta a origem desse “número mágico” é o próprio James Gosling, considerado o “pai” da linguagem Java:
Nós costumávamos ir almoçar num lugar chamado St. Michael’s Alley. De acordo com uma lenda local, a banda Grateful Dead costumava se apresentar por lá num passado distante, antes de se tornar famosa. Era um lugar muito peculiar, que definitivamente tinha tudo a ver com a Grateful Dead. Quando Jerry morreu, eles chegaram até a montar um pequeno santuário no estilo budista.
Quando combinávamos ir lá, referíamo-nos ao lugar como Cafe Dead (Café Morto). Num dado momento, percebeu-se que isso era um número hexadecimal. Naquela época eu estava atualizando o código de alguns formatos de arquivo e precisava de um par de números mágicos: um para o arquivo-objeto persistente e outro para as classes. Usei CAFEDEAD para o formato de arquivo-objeto e, ao buscar uma palavra com 4 caracteres hexadecimais para combinar com CAFE, que parecia bastante apropriado, acabei encontrando BABE e decidi usá-la. Naquele tempo, isso não parecia tão importante assim ou destinado a ter outro lugar na história além da lata de lixo.
Assim, CAFEBABE se tornou o formato do arquivo de classes, e CAFEDEAD era o formato do arquivo-objeto persistente. Mas a utilização do arquivo-objeto persistente foi abandonada, e com ele o uso de CAFEDEAD, eventualmente substituído pela RMI (Remote Method Invocation, ou seja, Invocação de Métodos Remotos).
Na figura abaixo, podemos ver esse famoso número mágico num arquivo .class editado no editor Sublime Text:
Um observação final: a “assinatura” CAFE BABE é usada de forma generalizada pelos bytecodes gerados por outras linguagens de programação que se utilizam da JVM, tais como Groovy e Scala.
Sintaxe das Linguagens de Programação
Dizem que certa vez um grande general, prestes a ir para a guerra, dirigiu-se ao Oráculo de Apolo, em Delfos, como era costume na Grécia Antiga, para consultar a Pitonisa sobre seu futuro. A Pitonisa, com sua voz gutural, disse-lhe a frase em destaque na figura acima, sem que a entonação de sua voz fizesse qualquer distinção sintática com pausas ou ênfases. Dessa forma, o general interpretou a profecia com a pontuação que aparece à direita, ficando tranquilo quanto ao seu sucesso.
Tempos depois, sua viúva dirigiu-se ao Oráculo e foi ter com a Pitonisa, para questioná-la quanto à falsidade de sua profecia, pois o general havia perecido na guerra. A Pitonisa respondeu-lhe que tinha havido um mal entendido, pois sua previsão fora correta, com a pontuação da mesma frase como aparece à esquerda na figura.
Se essa história é verdadeira ou apenas uma lenda, não sei dizer, mas serve para demonstrar a importância da sintaxe em qualquer linguagem.
De acordo com a Wikipédia, uma linguagem de programação pode ser definida como “um conjunto de regras sintáticas e semânticas usadas para definir um programa de computador” e, no caso de sua inobservância, ao invés de gerar apenas mal entendidos, como no caso das linguagens naturais, é gerado um erro de compilação.
Apresento, na figura abaixo, um trecho do código-fonte de um programa Java, onde podemos observar a aplicação dessas regras na prática.
As palavras em destaque no texto, tais como public
, class
, static
e void
, são palavras reservadas para uso interno pela linguagem e cada uma tem sua razão de ser e uma função específica. Observem também os sinais gráficos especiais como chaves ({}
), colchetes ([]
), parênteses (()
) e o ponto e vírgula (;
) encerrando a declaração de um método. Atentem para a forma de composição do método: System.out.println(…)
, e as aspas delimitando a String "Olá mundão velho!"
. Enfim, tudo isso faz parte da sintaxe da linguagem de programação Java e qualquer erro, mesmo a simples troca de uma letra maiúscula por uma minúscula numa palavra reservada ou tipo de dado, acarreta um erro de sintaxe e, consequentemente, o programa não será compilado até que o erro seja corrigido.
Existem também certas convenções adotadas de forma consistente pela linguagem Java, que eu o aconselho enfaticamente a adotar desde logo, pois isso facilitará muito sua vida e a de outros programadores que precisarem examinar seu código, além de dar-lhe um aspecto bem mais intuitivo e profissional. É o caso, por exemplo, da adoção do estilo CamelCase para identificação de variáveis, classes e métodos personalizados, como, por exemplo, no código acima, a classe OlaMundo
. O programa iria compilar normalmente se você lhe desse o nome de OLAMUNDO
, mas isso estaria contrariando as convenções usuais da linguagem. Olhando de relance, um programador poderia pensar tratar-se de uma constante, onde todas as letras são maiúsculas por convenção.
Deu para você entender por que a observância das convenções é tão importante? Embora isso possa ter ficado meio vago no exame de um trecho de código tão pequeno como este, podem acreditar que faz muito sentido quando se analisa um programa com centenas ou milhares de linhas de código!
Clareza do Código
Um outro aspecto que não deve ser relevado é com relação à estética de redação do código, com critérios de endentação, espaçamento e sinalização consistentes, para facilitar sua leitura e entendimento. Examine as duas versões de um mesmo fragmento de código na figura abaixo:
O código acima da linha tracejada é exatamente o mesmo daquele abaixo dela e esse programa compila normalmente, mas é evidente que a primeira versão é muito mais clara para a leitura e compreensão do código. Se isso é válido para um trecho de código-fonte tão pequeno, imagine num programa com centenas de classes e milhares de linhas.
Outro ponto importante, é manter a consistência de estilo ao longo do código-fonte. Se, por exemplo, você usa este estilo, abrindo a chave logo depois da declaração, na mesma linha:
public static void main (String[] args) { }
evite mudar para este outro estilo, abrindo a chave na linha seguinte à da declaração:
public static void main (String[] args) { }
A mudança é muito sutil: apenas o local de abertura da chave, mas uma vez escolhido um dos estilos, permaneça fiel a ele ao longo de todo o código. A mesma coisa vale para espaçamento de endentação e de linhas. Com o tempo, você vai observar que quando a formatação é consistente, fica mais fácil habituar-se com ela e isso agiliza a leitura do código. Nosso cérebro é incrível no seu poder de adaptação, mas um pouquinho de ajuda vai aumentar sua produtividade.
Neste particular, os editores das IDE facilitam muito a vida do programador, pois todos eles incorporam recursos para automatizar o processo de endentação e formatação do código-fonte, com bastante flexibilidade para atender a todos os gostos.
Para finalizar, um último conselho: usem e abusem dos comentários, principalmente da facilidade de documentação oferecida pelo Javadoc, pois isso é o que efetivamente separa os profissionais dos amadores.
Sintaxe de Java vs. Outras Linguagens
Comparem, a seguir, a sintaxe de um mesmo programa básico nas suas versões em Java, C, C++, C# e Python. Tirando Python, que é na verdade um script executado por um interpretador, todas as demais linguagens tem uma sintaxe muito parecida. Isso é feito propositalmente, para que a curva de aprendizado seja muito rápida de uma para outra linguagem. Uma vez dominada uma delas, o caminho para aprender as outras fica bem mais suave.
Em Java:
/* OlaMundo em Java */ public class OlaMundo { public static void main(String[] args) { System.out.println("Olá mundão velho!"); } }
Em C:
/* OlaMundo em C */ #include <stdio.h> int main (int argc, char** argv) { printf("Olá mundão velho!\n"); // função printf está em stdio.h return (0); }
Em C++:
/* OlaMundo em C++ */ #include <iostream> using namespace std; int main(int argc, const char * argv[]) { cout << "Olá mundão velho!" << endl; }
Em C#:
/* OlaMundo em C# */ using System; public class OlaMundo { public static void Main(string[] args) { Console.WriteLine("Olá mundão velho!"); } }
Em Python:
# OlaMundo em Python print "Olá mundão velho!"
Palavras Reservadas pela Linguagem Java
Para encerrar esta aula, apresento a seguir uma tabela com as 50 palavras reservadas da linguagem de programação Java, sendo que as duas últimas não são mais usadas atualmente, sendo mantidas apenas por uma questão de compatibilidade com suas primeiras versões.
Ao longo deste curso, teremos oportunidade de examinar essas palavras, todas amplamente documentadas. Encorajo-o a fazer uma pesquisa no Google sobre cada uma, principalmente as menos usuais, para ir se familiarizando com a sintaxe de Java.
Esta é, talvez, a parte mais trabalhosa no aprendizado de uma linguagem de programação. Seria comparável com a ampliação do vocabulário, para quem aprende uma língua estrangeira. Pode ser tedioso às vezes, mas somente quando você tiver domínio sobre um vocabulário suficientemente amplo, poderá deslanchar no idioma.