Programação Java II

Programação Java

1 Elementos básicos da linguagem Java

Variáveis em Java

Uma variável representa um endereço de memória no qual um valor está armazenado. Quando definimos variáveis em Java devemos considerar seu nome, tipo e um valor de inicialização. Lembre-se de que uma variável será definida dentro de um método, enquanto um atributo é definido dentro da classe. O nome da variável representa o rótulo usado para identificá-la no código. O tipo da variável determina o conjunto de valores que ela pode assumir, e o valor de inicialização deve ser atribuído à variável no momento de sua criação. É importante observar que uma variável definida internamente a um método só será visível dentro do método, enquanto um atributo será visível por todos os métodos da classe

Atributos em Java

Conforme já informado, um atributo deve ser criado após a definição da classe e fora de qualquer método, sendo que o atributo pode ser ainda classificado como não-estático ou estático. Um atributo não-estático existe enquanto o objeto estiver ativo, ou seja, seu valor será liberado depois que o objeto não for mais usado. Um atributo estático existe enquanto a classe na qual ele foi definido estiver carregada na JVM. O programa 01.07 mostra um exemplo do uso de atributo estático e não-estático.

Na classe ContaCorrente definimos o atributo cpmf como estático, assim, no método setCpmf(double cpmf) fizemos a atribuição ao atributo estático por meio do nome da classe (ContaCorrente.cpmf = cpmf), ou seja, um atributo estático deve sempre ser acessado pelo nome da classe. Apesar de ser possível acessar um atributo estático usando um objeto, devemos optar pelo nome da classe. O programa 01.08 mostra um exemplo de uso do atributo estático apresentado no programa 01.07.

O resultado da execução do programa é:

No programa 01.08 estamos acessando o atributo estático por meio de um objeto (objeto2.cpmf = 0.0010) e do nome da classe (ContaCorrente.cpmf = 0.0038). O acesso realizado por meio do nome do objeto foi usado apenas para demonstrar que, quando alteramos o valor de um objeto, os outros objetos passam a visualizar o valor alterado. Porém, de acordo com as boas práticas, devemos sempre acessar um atributo estático por meio do nome da classe.

Tipos primitivos

Os tipos primitivos da linguagem Java são muito parecidos com os usados na linguagem C, assim, se você tiver experiência com a linguagem C, não terá dificuldades para entender os tipos primitivos da linguagem Java. A tabela 1.5 mostra os tipos primitivos da linguagem Java.

Tabela dos tipos primitivos da linguagem Java

Tipos de dados Referência

Toda classe criada pelo programador ou pela Sun representa um tipo de dado diferente dos tipos primitivos (int, double, float etc.) já apresentados. Um exemplo é a classe ContaCorrente. Ela representa um novo tipo de dado.

Quando criamos objetos do tipo da classe ContaCorrente estamos criando um atributo ou variável do tipo referência. Uma variável do tipo referência, quando passada como parâmetro, terá um comportamento diferente de um tipo de dado primitivo, ou seja, caso o parâmetro passado seja alterado no método chamado, este terá seu valor alterado também quando retornar a execução ao método ativador. Se passarmos um parâmetro do tipo primitivo, as alterações realizadas neste não serão refletidas no método ativador.

Operadores aritméticos

Os operadores aritméticos representam as operações básicas da matemática. A tabela 1.6 apresenta os operadores, seu uso e uma breve descrição.

Operadores aritméticos

O programa 01.09 mostra um exemplo do uso dos operadores aritméticos.

O resultado da execução do programa é:

2 Operadores unários

Os operadores unários realizam as operações básicas levando em consideração apenas uma variável. A tabela abaixo apresenta os operadores unários.

Operadores unários

O programa 01.10 mostra um exemplo do uso dos operadores unários.

O resultado da execução do programa é:

Operadores relacionais

Os operadores relacionais realizam as operações de igualdade e comparação. A tabela abaixo apresenta os operadores relacionais.

O programa 01.11 mostra um exemplo do uso dos operadores relacionais.

O resultado da execução do programa é:

Operadores lógicos

Os operadores lógicos são muito usados em estruturas de controle e loop. A tabela 1.9 apresenta os operadores lógicos.

Tabela Operadores lógicos

Operadores de atribuição

Os operadores de atribuição são usados para atribuir um novo valor a uma variável. A tabela 1.10 mostra os operadores de atribuição.

Tabela Operadores de atribuição

Estruturas de controle

A linguagem Java disponibiliza os comandos if e else que, de forma seletiva, definem qual bloco de comandos deverá ser executado. Se a condição do comando if for avaliada como verdadeira será executado o bloco de comandos dentro do if. Caso contrário, o bloco de comandos dentro do else será executado. O programa 01.12 mostra um exemplo do comando if.

A condição (var1 > var2) sempre retornará um valor lógico, ou seja, verdadeiro ou falso. Caso verdadeiro, o bloco de comandos abaixo da condição será executado, caso contrário, não haverá execução. Caso o comando if retorne falso, podemos encadear a execução de um segundo bloco de comandos do comando else. O programa 01.13 mostra um exemplo envolvendo o comando if e o else.

Além dos comandos if e else há o comando switch, que também realiza a execução de um bloco de comandos de acordo com uma decisão. Muitos programadores se perguntam quando devem usar o switch e quando devem utilizar o comando if. Qual dos dois comandos será mais útil?

O uso de cada um dos comandos depende da composição da estrutura de decisão. Devemos optar por usar o comando switch quando, no teste realizado, usarmos uma mesma variável, igualando-a com vários valores diferentes. O programa 01.14 mostra um exemplo do uso do comando if, enquanto o programa 01.15 mostra um exemplo do mesmo programa com o comando switch.

Quando usamos o comando switch devemos também usar em conjunto o comando case, que com base no valor da variável do comando switch define qual opção será executada. Para que somente um entre os vários comandos case seja executado, devemos executar o comando break, logo após a execução dos comandos contidos no bloco do comando case selecionado.

Quando quisermos que um mesmo bloco de comandos seja executado, para dois ou mais diferentes valores do comando switch, devemos encadear a execução dos comandos case sem a execução do comando break entre eles. Somente executamos um comando break ao final dos comandos executados. É importante observar que o comando break interrompe a execução do case.

Há também o comando default, que representa uma exceção a todas as opções listadas nos comandos case. É importante observar que no comando switch só são aceitas variáveis do tipo int ou char. O uso de outro tipo primitivo gera um erro de compilação.

Nesse programa leremos no teclado um caractere, e caso seja igual às letras da palavra Java, exibirá a mensagem "Letra digitada está correta.". Caso contrário, veremos Letra digitada está incorreta. A linha else if ((char) numero == (char) 13) do programa 01.14 está verificando se o usuário digitou a tecla . O valor dessa tecla na tabela ASCII é igual ao valor 13 no formato caractere. Ou seja, se o usuário não digitar nenhuma letra e apenas teclar no teclado, será emitida uma mensagem de alerta. Neste exemplo usamos o comando import java.io.IOException. O comando considera dois elementos: o comando import e a classe de exceção IOException. Este livro aborda o comando import e apresenta de forma detalhada, no capítulo 7, todos os elementos necessários para o tratamento de exceções em Java.

O programa 01.15 representa outra forma de obter o mesmo resultado que tivemos com o programa 01.14, usando o comando switch em vez do if.

3 Processo de avaliação com os operadores

A linguagem Java realiza a avaliação curta quando usamos os operadores lógicos && e ||. Ou seja, dependendo da avaliação parcial do comando if, por exemplo, não será necessário a avaliação da outra expressão. Quando usamos o operador &&, caso a primeira condição avaliada em um comando if seja falsa, automaticamente a segunda expressão não será avaliada.

Quando usamos o operador ||, caso a primeira condição avaliada em um comando if seja verdadeira, automaticamente a segunda expressão não será avaliada. Caso seja necessário que toda a expressão seja avaliada independentemente das validações anteriores, podemos usar os operadores & e |.

O programa 01.16 exemplifica o uso desses operadores. Neste exemplo usamos a classe Console para enfatizar o comportamento dos operadores apresentados. A classe Console poderá ser obtida na internet ou na página deste livro no site da Novatec. É importante observar que até a versão 1.4 do J2SE os mecanismos de leitura de dados a partir do teclado eram de uso complexo. Para contornar essa complexidade foi criada a classe Console, que tem como objetivo facilitar a leitura dos dados em programas Java.

É importante observar que a classe Console usada neste livro não corresponde à classe Console presente no pacote java.io.Console. A classe java.io.Console foi criada na versão 1.6 do J2SE e deve ser usada quando um programa java é executado a partir de um console, ou seja, não atende às necessidade dos exemplos presentes neste livro. A classe Console usada neste livro deverá ser obtida da internet ou do site da editora Novatec, conforme comentado.

Para executar os exemplos é necessário que o leitor tenha a classe console em seu ambiente de desenvolvimento.É importante observar também que em outros exemplos será necessário realizar o download de arquivos com a extensão .jar, com o objetivo de evitar os erros de compilação causados pela falta deles. Quando houver algum exemplo que use algum recurso especial, descreveremos no próprio programa essa necessidade.Todos os recursos necessários para a execução dos exemplos deste livro poderão ser obtidos na página da editora Novatec.

A partir da versão 1.5 do J2SE foi lançada a classe Scanner, que pode ser usada como uma alternativa à classe Console. A vantagem de usá-la é que já está presente na instalação do J2SE versão 1.5 ou superior, enquanto a classe Console deve ser obtida em sites externos. O capítulo 8 apresenta de forma detalhada a classe Scanner. Contudo, faremos um uso intensivo dessa classe para realizar a leitura de dados por meio do teclado em diversos exemplos deste livro.

No exemplo apresentado no programa 01.16 usamos a classe Console para realizar a leitura dos dados a partir do teclado. Como podemos observar, essa classe está gravada no pacote modulo01.estudodecaso.util, ou seja, para que o exemplo funcione, é necessário colocar a classe Console na mesma estrutura hierárquica de pacotes usada neste exemplo, além de executar o comando import para evitar um erro de compilação.

Para não gerar erro de compilação ao digitar o programa é preciso, a partir do nome do projeto, criar o pacote modulo01.estudodecaso.util e copiar a classe Console obtida do site para dentro do pacote. A partir desse momento, o exemplo funcionará corretamente. É importante observar que esse mesmo procedimento será usado por outros exemplos deste livro. O capítulo 2 apresenta de forma detalhada o conceito de pacotes (package, em inglês) e o comando import.

Estruturas de repetição

O primeiro comando que abordaremos é o for, que executa um bloco de comandos determinado várias vezes. A figura abaixo apresenta a sintaxe do comando for, e a representação gráfica do comando quando executado de forma procedural.

O programa abaixo exemplifica o comando for.

O programa exibirá os números entre 0 e 26 na tela do computador.Conforme comentado, devemos usar o comando for quando sabemos de antemão quantas vezes o loop deverá ser executado. Quando o fim de um loop depender da entrada do usuário devemos optar pelo uso do comando while, que executa um bloco de comandos enquanto sua condição for verdadeira. A figura 1.6 mostra um exemplo da sintaxe do comando while, e a representação gráfica do comando.

O programa 01.18 mostra um exemplo do uso do comando while.

Há ainda uma terceira opção de comando de loop conhecido por do while. Difere do while no sentido de permitir que pelo menos uma execução do bloco de comandos seja executada antes de testar a condição. O bloco de comandos será executado enquanto a condição for verdadeira. A figura abaixo mostra um exemplo da sintaxe do comando do while, e a representação gráfica do comando.

 

O programa 01.19 mostra um exemplo do comando do while.

O comando do while será usado nos laboratórios deste livro para a validação da entrada dos dados via teclado.

4 Comando break

O comando break tem a função de interromper a execução de um loop. É possível também, com o comando break, interromper um loop presente em um nível superior ao loop onde o break será executado. Para isso usamos labels. O programa 01.20 exemplifica o comando break, com e sem uso de labels.

Comando continue

O comando continue tem a função de fazer com que a condição do comando de loop seja novamente testada, mesmo antes de alcançar o fim do comando. O programa 01.21 mostra um exemplo do comando continue.

Comandos de entrada

Os comandos de entrada disponíveis nas primeiras versões da linguagem Java sempre representaram uma grande dificuldade para o desenvolvedor. Somente na versão do J2SE 5.0 é que o problema foi resolvido, com a inclusão da classe Scanner, disponível no pacote java.util.Ou seja, para usar essa classe devemos usar o comando import java.util.Scanner antes da criação da classe. O programa 01.22 traz um exemplo do uso da classe Scanner realizando a leitura dos dados pelo teclado.

O programa 01.22 mostra um segundo exemplo do uso da classe Scanner. Neste exemplo, realizaremos a leitura dos dados usando como fonte de dados um arquivo. Para executar esse programa e ter acesso ao arquivo, este deverá ser criado dentro do pacote onde o código-fonte do programa Java está gravado.

A classe Scanner permite a leitura de tipos de dados primitivos e strings. No primeiro exemplo do programa 01.22 a fonte usada para leitura foi o teclado (System.in), e o tipo primitivo lido, o int. No segundo exemplo, a fonte de leitura foi um arquivo, e o tipo de dado primitivo, o long.

Comandos de saída

Nos exemplos já apresentados no livro usamos em diferentes lugares o comando System.out.println ("texto qualquer") para apresentar um determinado resultado na tela. Esse comando é o mais usado para a apresentação de dados quando o desenvolvimento do programa Java é batch. Este exemplo usa o atributo estático out, definido na classe System, que por sua vez executa o método println(). O atributo out representa um stream de saída padrão e é um atributo do tipo da classe PrintStream.

Na versão do J2SE 1.5 foi disponibilizado na classe PrintStream o método printf(), que oferece os mesmos recursos já conhecidos na linguagem C. Logo, podemos usar um formato de saída padrão muito parecido com o disponível na linguagem C.O programa 01.24 exemplifica o atributo out usando o método printf(). É importante observar que o método printf() está presente apenas a partir da versão 1.5 do J2SE. Caso seu ambiente ainda não esteja configurado para essa versão, um erro de compilação será exibido

O resultado desse programa será: