Introdução

Na segunda aula do Curso de Java, começamos, como se costuma dizer, a colocar a mão na massa! Hora de codificar nosso primeiro programa em Java: o famoso HelloWorld, versão tupiniquim.

Mostramos como é feita a compilação e execução de um programa Java através da linha de comando do Windows (ou terminal, no Mac e Linux), dissecamos os comentários em Java, analisamos os problemas de acentuação (não só em Java) e a codificação UTF-8 e, para encerrar, falamos sobre os erros que podem ocorrer durante a compilação e/ou execução de um programa.

Programa da aula:

Sintaxe Básica

Uma das razões do grande sucesso da linguagem de programação Java foi, sem sombra de dúvida, adotar uma sintaxe quase idêntica à das linguagens C/C++, que já contavam naquela época com uma ampla e sólida base de programadores, os quais puderam, assim, aprender as particularidades da nova linguagem com muita facilidade, atingindo rapidamente uma alta produtividade.

Os criadores da linguagem Java, contudo, não se preocuparam apenas em dar-lhe uma sintaxe de aparência familiar, mas também, desde o início, estabeleceram regras para a redação do código, de forma a torná-lo compreensível e de fácil manutenção. Tais convenções, de fato, induzem bons hábitos de programação e, por essa razão, Java tem sido cada vez mais adotada nas escolas, de todos os níveis, para o ensino de programação.

Nosso primeiro programa: "OlaMundo.java"

Já é uma tradição, para fazer uma rápida apresentação de qualquer linguagem, escrever um pequeno programa que contenha sua sintaxe básica, o qual, normalmente, consiste em exibir a mensagem "Hello world!" (Olá mundo!) no console ou terminal do computador.

Não vamos fugir à regra. Abaixo, está o código do programa HelloWorld, adaptado para a nossa versão tupiniquim, com o nome OlaMundo:

/* OlaMundo em Java */

public class OlaMundo {

	public static void main(String[] args) {

		System.out.println("Olá mundão velho!"); // exibe mensagem

	}

}

Vamos analisar os componentes desse pequeno programa e vocês já vão entender porque eu disse que as convenções da linguagem Java induzem boas práticas de programação.

Comentários em Java

Na linha 1 acima, encontramos um comentário, ou seja, um texto que serve apenas como referência para o programador entender a finalidade do programa ou explicar determinado trecho do código. Fazem parte do que denominamos metadados, ou seja, informações inseridas no código a respeito dele próprio.

Esta sintaxe para comentários é exatamente idêntica à da linguagem C, também disponível em C++, começando sempre com o conjunto de caracteres /* e terminando com o conjunto */. Tudo o que for escrito entre esses dois conjuntos será desconsiderado pelo compilador na geração do bytecode. Esta fórmula permite a inserção de comentários de diversas linhas, de forma bastante prática. Alguns costumam "emoldurar" o texto do comentário, de forma a destacá-lo mais no corpo do código, como a seguir:

/*===================================================
* Programa: Loterias.java                           *
* Autor: Fulano de Tal                              *
* Data: 25/12/2014                                  *
====================================================*/

Esta é uma forma perfeitamente válida de comentário multilinhas em Java. Observe que ele inicia com o conjunto /* e termina com o conjunto */, como determina a sintaxe da linguagem.

Outra forma de escrever comentários é precedendo-os do conjunto //, o que também é muito usual em C++. Você encontra um exemplo deste tipo de comentário no final da linha 7 no nosso programinha "OlaMundo" acima.

A grande diferença deste tipo de comentário em relação ao primeiro que examinamos (/* ... */), é que ele não permite múltiplas linhas de comentário como o anterior. Isso é óbvio, pois possui apenas um conjunto de caracteres inicial, mas é bastante prático para comentar linhas de código, bem como para excluir temporariamente determinada linha ou trecho de linha para algum teste que precisemos fazer.

Na linguagem Java existe um terceiro tipo de comentário, peculiar a ela, ou seja, não é encontrada em C/C++. Ele também permite comentar múltiplas linhas e sua sintaxe é quase igual à do comentário multilinhas normal. A diferença é que possui um asterisco (*) a mais no conjunto de abertura, isto é, começa com /** e termina com */.

Sendo Java uma linguagem orientada a objetos, uma de suas características marcantes é a possibilidade de reutilização do código das classes criadas. Para isso, evidentemente, é preciso que o código esteja muito bem documentado, descrevendo todas as peculiaridades das classes, seus parâmetros, métodos, etc.

É exatamente aí que entra em cena a ferramenta JavaDoc, incluída na instalação do JDK, que facilita todo o trabalho de criação e manipulação dos comentários.

Nós vamos dedicar um aula especial para estudar JavaDoc, mas para que você já faça uma ideia do seu funcionamento, ele opera através da marcação de documentos, gerando arquivos nos formatos HTML, SGML, XML ou RTF. Veja, a seguir, um exemplo de comentário JavaDoc, destacando-se as tags iniciadas com @:

/** Classe para objetos tipo Servidor, contendo seus valores e metodos
 *  @author J. A. Gaeta Mendes
 *  @version 2.35
 */

(Quase) tudo em Java é uma classe

Continuando com a análise do nosso programa de apresentação, encontramos na linha 3 o início do código propriamente dito, ou seja, aquele que será efetivamente compilado no bytecode:

public class OlaMundo {

Como já mencionamos diversas vezes, Java é uma linguagem quase totalmente orientada a objetos. De fato, tirando os tipos primitivos, tudo em Java é uma classe que, como veremos mais tarde, são as "plantas" ou "esquemas" para a criação de objetos. Assim, todo o programa em Java é composto ao menos por uma classe.

Demos à classe deste nosso primeiro programa o sugestivo nome OlaMundo. Os nomes dados às classes, bem como às variáveis que veremos adiante, são tecnicamente denominados identificadores.

Observem com cuidado a forma como o identificador foi escrito: começa com letra maiúscula, sempre que for nome de classe. Como não são permitidos espaços entre palavras nos identificadores, quando eles são compostos de mais de uma palavra, como no nosso caso, usa-se uma forma chamada em inglês "CamelCase", que consiste em iniciar cada palavra com uma letra maiúscula, imitando as corcovas de um camelo, daí o nome. Estas convenções, como já disse, devem ser rigorosamente observadas, para facilitar a análise e manutenção do código. A medida em que seus programas forem ficando mais complexos e extensos, você vai entender a relevância disso.

Outra observação muito importante é que o nome do arquivo salvo no editor de textos deverá ser exatamente o mesmo daquele dado à classe, observando-se rigorosamente a caixa das letras, pois Java faz distinção entre maiúsculas e minúsculas, acrescentando-se a extensão .java (no nosso caso, o nome do arquivo será OlaMundo.java). Oficialmente, cada arquivo-fonte em Java é chamado "Unidade de Compilação".

Palavras-reservadas, modificadores e chaves

Analisemos agora as duas palavrinhas que antecedem o identificador da classe. Uma delas, class, é uma palavra reservada da linguagem, usada para declarar que uma nova classe está sendo definida. Existem 50 palavras reservadas na linguagem Java, conforme estudaremos adiante, sendo class uma delas.

A outra é o modificador de acesso public, mais uma palavra reservada, que permite ao programador controlar a visibilidade dos membros da classe. Quando um membro de uma classe é precedido da palavra public, ele pode ser acessado por código externo à classe no qual ele é declarado. (O oposto de public é private, que impede que um membro seja usado por código externo à sua classe. Veremos isso com mais detalhes em aulas específicas).

Finalmente, observamos a abertura de uma chave ({). Toda a definição da classe, inclusive de todos os seus membros, será entre a chave de abertura e fechamento ({}). Por ora, não se preocupe muito com os detalhes da classe. Apenas observe que em Java, toda a atividade do programa ocorre dentro de uma delas.

O método main()

Passemos para a linha seguinte do programa:

public static void main(String[] args) {

Esta linha inicia o método main() e é nela que o programa começará a ser executado. Observe a chave de abertura para este novo bloco, que terá sua correspondente de fechamento na linha 9. Cada parte entre as chaves é denominado um bloco de código.

Todo aplicativo Java começa sua execução invocando o método main(). O significado completo de cada uma de suas partes não pode ser explicado já, uma vez que exige um entendimento detalhado da forma como Java implementa o encapsulamento.

Todavia, como vamos usá-lo bastante desde o início do nosso curso, não custa dar uma rápida examinada em cada um dos seus componentes.

A primeira palavra, o modificador de acesso public, já examinamos acima e, de fato, o método precisa ser assim definido, uma vez que será acessado por código externo quando o programa for executado.

A palavra reservada static permite que main() seja chamado sem necessidade de ser instanciado. Instanciar, significa criar um objeto com base no "esquema" representado pela classe. Isso é necessário uma vez que main() é invocado pela JVM (Java Virtual Machine) antes que os objetos sejam criados.

A palavra reservada void apenas informa o compilador que main() não vai retornar nenhum valor. Como veremos mais tarde, os métodos também podem retornar valores.

Se tudo isso lhe pareceu meio confuso, não se preocupe porque, como já disse, iremos abordar tudo com detalhes em aulas posteriores.

Para passar informações a serem processadas pelo método, usam-se variáveis especificadas dentro dos parênteses que seguem o identificador que, no caso de métodos, devem sempre começar com letra minúscula, bem como os das variáveis.

Essas variáveis são denominadas parâmetros. Mesmo que não sejam necessários parâmetros para o método, ainda assim deve ser incluído um conjunto de parênteses vazio. Embora o método main() possua apenas um parâmetro, ele é bem complicadinho... Vamos destrinchá-lo!

String[] args declara um parâmetro denominado args, que é um array de instâncias da classe String. Iremos estudar os arrays em aula específica, mas adianto que são coleções de objetos similares. Objetos do tipo String armazenam cadeias de caracteres. Neste caso, args recebe todos os argumentos passados na linha de comando quando o programa é executado.

Mais uma coisinha: o método main() é apenas um ponto de entrada no seu programa. Um programa complexo terá dezenas ou até centenas de classes, mas apenas uma delas possuirá o método main() para início do programa. Em algumas situações, aliás, o método main() é até mesmo dispensável. No caso dos applets, por exemplo — programas Java embutidos em navegadores Web — não será preciso usar main(), uma vez que os navegadores Web usam outros métodos para iniciar a execução dos applets.

O método println()

Analisemos, para terminar, a última linha de código:

System.out.println("Olá mundão velho!"); // exibe mensagem

Esta linha exibe a String "Olá mundão velho!", inserindo uma nova linha ao final, no console ou terminal de vídeo para onde está direcionada a saída-padrão. A saída é implementada pelo método println(). Neste caso, println() exige a String que lhe é passada como parâmetro. A linha começa com System.out. Embora seja meio complicado explicar isso neste ponto do curso, System é uma classe pré-definida que dá acesso ao sistema operacional, e out é a stream de saída conectada ao console.

Os métodos de entrada e saída via console, evidentemente, não são muito aplicados no mundo real da programação Java, uma vez que os ambientes operacionais modernos possuem uma interface gráfica. Todavia, tendo em vista sua simplicidade de uso, são ótimos para demonstrações e iremos usá-los bastante na parte inicial do curso, até apresentarmos outras formas de entrada/saída de dados usando Java.

Observe que a declaração do método println() termina com um ponto-e-vírgula (;). Todas as declarações em Java terminam com um ponto-e-vírgula e o motivo pelo qual as outras linhas não terminam dessa forma é porque não são, tecnicamente, declarações.

A primeira } (linha 9) no programa encerra o bloco de código de main(), e a útima } (linha 11) encerra a definição da classe OlaMundo.

Edição do código-fonte

Para implementar nosso primeiro programa na linguagem Java, a primeira coisa a fazer é criar o arquivo do código-fonte examinado na seção anterior.

Para isso, você poderá usar qualquer editor de textos que salve arquivos de texto puros, ou seja, sem nenhuma formatação especial. Dois bons editores, ambos com versões gratuítas, são o Notepad++ e o SublimeText. Mas poderá ser usado qualquer editor mais simples, como o Bloco de Notas do Windows, o Leafpad no Linux ou o TextEdit no Mac OS X.

Para esta demonstração, vamos usar o SublimeText. Copie o código-fonte do programa "OlaMundo", tomando cuidado para reproduzir tudo fielmente, pois qualquer pequeno equívoco irá gerar um erro na compilação. Cuidado, em especial, com a caixa das letras, pois o compilador faz distinção entre maiúsculas e minúsculas. Observe, também, o ponto-e-virgula que encerra a declaração e os pares de chaves, parênteses e colchetes.

Salve o arquivo com o nome OlaMundo.java. Como já mencionamos, é essencial que o nome dado ao arquivo do código-fonte seja exatamente o mesmo que foi dado à classe, para que não ocorra um erro durante a compilação. Na figura abaixo, vemos a caixa de diálogo do Windows para salvar o arquivo a partir do editor Sublime:

O editor SublimeText, como outros, reconhece o tipo de arquivo como código-fonte Java a partir da extensão (.java) e faz o realce das palavras-chave de acordo com a sintaxe da linguagem (syntax highlighting), facilitando muito a visualização do código. Todos os IDE, como o Eclipse que iremos usar neste curso, também possuem esta funcionalidade nos seus editores. Observe como o texto do código ficou todo colorido na próxima figura:

sublime_win

Aproveite para conferir, no painel da esquerda, que o nome do arquivo, "OlaMundo.java" corresponde exatamente o nome da classe (OlaMundo).

Compilação

Compilar o código-fonte significa usar um programa, chamado compilador, o qual irá ler as definições da classe, escritos na linguagem de programação Java e compilá-las em um arquivo bytecode da classe, que também terá o mesmo nome dela, variando apenas a extensão, que será ".class", ao invés de ".java".

O compilador Java faz parte do JDK e é chamado javac. A forma geral para invocá-lo a partir da linha de comando, é a seguinte:

javac [opções] [arquivos-fonte] [classes] [@argfiles]

Os argumentos podem ser colocados em qualquer ordem e representam:


  • opções: as opções de linha-de-comando.

  • arquivos-fonte: um ou mais arquivos-fonte a serem compilados (como OlaMundo.java).

  • classes: uma ou mais classes a serem processadas para anotações (como OlaMundo.class).

  • @argfiles: um ou mais arquivos que listam opções e arquivos-fonte.

Como você pode ver, o programa possui muitas funcionalidades, inclusive para geração de documentação. Para consultar um resumo de todas as opções disponíveis, use o comando: javac -help. Será exibida a relação completa das opções, conforme a figura abaixo:

javac_help

Na documentação da Oracle encontram-se todos os pormenores para usar o programa javac em toda a sua potencialidade.

Na verdade, todo o desenvolvimento em Java pode ser feito apenas com um editor de textos e os programas de linha de comando javac, para compilação do aplicativo e java, para sua execução. Evidentemente, os IDEs facilitam muito a vida do programador, mas é muito importante saber como as coisas acontecem nos bastidores.

Para compilar nosso pequeno programa "OlaMundo", acesse o diretório onde o programa foi salvo. Desta forma, não precisamos nos preocupar com o caminho (path) onde está o arquivo, embora haja opções para sua localização a partir de qualquer lugar. Fazemos isso para simplificar o comando. Digite: javac OlaMundo.java e seu programa será compilado, gerando o arquivo OlaMundo.class.

Uma dica para quem usa o Windows: para abrir uma janela do prompt de comando em determinada pasta, clique com o botão direito do mouse, enquanto aperta simultaneamente a tecla Shift, sobre a área da caixa de diálogo do Windows Explorer correspondente à pasta onde deseja abrir o prompt de comando e selecione a opção Abrir janela de comando aqui. Consulte a figura a seguir:

win_open_cmd

Observe que é preciso passar o nome seguido da respectiva extensão (.java) para o programa javac. Digite o comando: javac OlaMundo.java. Depois de uma brevíssima pausa, reaparece o prompt de comando. Isso significa que seu programa compilou sem nenhum erro, pois, caso contrário, estes seriam exibidos. Confira que foi gerado o arquivo OlaMundo.class na pasta onde o código-fonte foi compilado. Veja o resultado na figura abaixo:

olamundo_class

Se quiser ver o compilador em ação, use a opção -verbose. O comando seria, então: javac -verbose OlaMundo.java. Veja como o compilador acessa a biblioteca-padrão java.lang, e quanta coisa é incorporada ao seu código. Essa é a grande sacada da programação orientada a objetos: eles podem ser usados mesmo sem conhecer os detalhes de sua implementação. É como dirigir um carro, sem precisar saber como funciona seu motor, ou conhecer a composição química do combustível usado.

Execução

O programa java executa o aplicativo Java e sua forma na linha-de-comando é a seguinte:

java [opções] classe [argumentos]

Existem muitas outras funcionalidades e outro programa parecido: o javaw, cujos detalhes podem ser consultados na documentação da Oracle. Para examinar as opções de linha-de-comando disponíveis, use o comando: java -help.

Para executar nosso bytecode compilado em OlaMundo.class, digite o comando: java OlaMundo. Observe que não deve ser digitada a extensão do arquivo (.class). Veja o resultado no prompt de comando do Windows na figura a seguir:

olamundo_exec

O resultado no prompt de comando do Windows é meio estranho, pois ele não decodifica corretamente os caracteres acentuados e a string exibida é:

Olá mundão velho!

Isso não acontece nos sistemas operacionais Linux e Mac OS X, nos quais a string é apresentada corretamente acentuada, como na figura seguinte, do terminal do linux:

olamundo_linux

Caracteres Unicode

O motivo disso é que o prompt de comando do Windows em português (cmd.exe), usa a página de código 850 (Multilingual - Latin I), enquanto Java usa a codificação UTF-16 para objetos String. Use o comando chcp  para conferir. Uma solução seria trocar a página de código para UTF-8, usando o comando: chcp 65001. Mas há uma solução melhor: use os caracteres de escape /u para inserir o código Unicode do caracter acentuado. O código-fonte do nosso programa ficaria então como abaixo:

/* OlaMundoUnicode em Java */

public class OlaMundoUnicode {

	public static void main(String[] args) {

		System.out.println("Ol\u00e1 mund\u00e3o velho!");

	}

}

Compile o novo programa (javac OlaMundoUnicode.java) e execute-o (java OlaMundoUnicode). O problema está resolvido, conforme pode ser visto na figura a seguir:

OlaMundoUnicode

Forneço a seguir uma tabela com os códigos Unicode dos caracteres latinos acentuados:

"á = \u00e1" "ê = \u00ea" "Î = \u00ce" "ú = \u00fa"
"à = \u00e0" "è = \u00e8" "Ï = \u00cf" "ù = \u00f9"
"â = \u00e2" "É = \u00c9" "ó = \u00f3" "û = \u00fb"
"ã = \u00e3" "È = \u00c8" "ò = \u00f2" "ü = \u00fc"
"ä = \u00e4" "Ê = \u00ca" "ô = \u00f4" "Ú = \u00da"
"Á = \u00c1" "Ë = \u00cb" "õ = \u00f5" "Ù = \u00d9"
"À = \u00c0" "í = \u00ed" "ö = \u00f6" "Û = \u00db"
"Â = \u00c2" "ì = \u00ec" "Ó = \u00d3" "ç = \u00e7"
"Ã = \u00c3" "î = \u00ee" "Ò = \u00d2" "Ç = \u00c7"
"Ä = \u00c4" "ï = \u00ef" "Ô = \u00d4" "ñ = \u00f1"
"é = \u00e9" "Í = \u00cd" "Õ = \u00d5" "Ñ = \u00d1"
"Ö = \u00d6" "Ì = \u00cc"

Para o desenvolvimento de programas complexos será realmente imprescindível o uso de um IDE como o Eclipse ou NetBeans, mas esses programas usam essas mesmas ferramentas básicas do JDK, de forma que é importante conhecer a fundo seu funcionamento, para otimização do próprio IDE e sua adequação às necessidades do seu projeto.

Erros de compilação

Uma das grandes vantagens de uma linguagem de programação fortemente tipada como Java, é a possibilidade de identificar erros de sintaxe durante a compilação do código.

Veja o que acontece quando tentamos compilar o código abaixo:

public class OlaMundoUnicode {

	public static void main(string[] args) {
		System.out.println("Ol\u00e1 mund\u00e3o velho!");

	}

}

ErroCompilacao

Como podemos observar, ocorreu um erro durante a compilação do programa, e não foi gerado o arquivo .class com o bytecode correspondente.

Neste caso, o compilador informa com precisão o local da ocorrência do erro: a palavra "String" na linha 3 foi escrita com um "s" minúsculo e, como já enfatizamos, Java faz distinção entre a caixa das letras. Basta efetuar a correção para um "S" maiúsculo, que o programa compilará sem nenhum problema.

Existem outros erros de sintaxe apontados pelo compilador, que não são rastreados de forma tão direta, mas podemos contar com utilitários especializados, chamados "debuggers", que estudaremos mais adiante, os quais facilitam nossa vida na identificação desses erros.

Erros de execução

Um outro tipo de erro pode ocorrer depois do programa ser compilado normalmente, e só é identificado durante sua execução. Observe o código e a figura abaixo:

public class OlaMundoUnicode {

	public static int main(String[] args) {
		System.out.println("Ol\u00e1 mund\u00e3o velho!");

	}

}

ErroExecucao

Aqui nós desrespeitamos a sintaxe do método main() e estamos tentando retornar um valor inteiro enquanto, conforme já comentamos, este método não deve retornar valor algum.

Novamente somos informados do erro e, também neste caso, o motivo do erro é explicitamente declarado: erro na sintaxe do método main(), cujo retorno deve ser modificado para void.

Existem outros tipos de erros ainda mais difíceis de localizar, como os erros na lógica do programa, mas isso vamos deixar para ver mais adiante, quando estudarmos os debuggers usados pelos IDE e outros programas específicos para esse tipo de depuração.

java-logo


comments powered by Disqus