Baixe o app para aproveitar ainda mais
Prévia do material em texto
Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento A Linguagem JAVA - 1ª Parte “O homem ainda é o computador mais extraordinário” − John F. Kennedy Introdução e Histórico O Java tem uma história curiosa: nasceu para ser usado por pequenos dispositivos (PDA’s, eletrodomésticos, etc...), mas se popularizou no outro extremo, sendo usado para grandes dispositivos (servidores), para depois ser usado para pequenos dispositivos (celulares, set- top-boxes de TV Digital). Em 1991, um grupo de funcionários da Sun Microsystems iniciou um projeto da empresa para desenvolvimento de programas para pequenos dispositivos denominado com o codinome Green. A idéia inicial era realizar a programação dos chips de tais dispositivos de modo a aumentar suas possibilidades de uso. Entretanto, o desenvolvimento de programas específicos para tais dispositivos inviabilizaria o projeto, pois os programas teriam que ser escritos para cada um dos dispositivos. A equipe, então, se voltou para construir um sistema operacional comum para tais dispositivos. Esse novo sistema operacional seria escrito em C++, porém a equipe encontrou problemas para desenvolver o sistema operacional nessa linguagem e optou por outra saída: construir uma nova linguagem. James Gosling, chamou então aquela linguagem de OAK em homenagem a uma árvore de carvalho vista de sua janela na Sun. Porém aquele foi inviabilizado visto já havia uma linguagem de computador chamada OAK. Então, quando a equipe da Sun visitou uma cafeteria local, o nome Java (cidade de origem de um tipo de café importado) foi sugerido; e o nome pegou. Essa nova linguagem sofreu influências de outras linguagens orientadas a objeto, como Eiffel, SmallTalk e Objective C, enquanto sua sintaxe foi baseada no C e C++. 1 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Em 1993 foi lançado o produto final dessa empreitada: o Star7, um avançado PDA. Entretanto, o Star7 foi um fracasso no mercado. Nessa época, a Sun decidiu abandonar a ênfase nos dispositivos eletrônicos e voltar-se para a Internet, que começava a crescer. Até 1994, o Java não tinha um futuro certo. Neste ano, foi criado um novo navegador para a Web (batizado de WebRunner) que era capaz de executar programas escritos em Java pela Internet. Este navegador foi apresentado pela Sun no SunWorld’95 como o navegador HotJava, em conjunto com o ambiente de desenvolvimento Java. Em 1995, a Netscape licenciou a tecnologia Java e lançou uma nova versão de seu navegador, capaz de executar aplicativos Java, agora denominados applets. Em 1996, numa iniciativa inédita, a Sun disponibilizou gratuitamente um kit de desenvolvimento de software para a comunidade, que foi chamado Java Developer’s Kit (JDK). Desde então, o Java tem evoluído muito. Mais tarde, o Java começou a ser utilizado no ambiente para o qual foi desenvolvido, com o J2ME (Java 2 Micro Edition). Em 2009, em uma transação de mais de US$7 bilhões a Oracle comprou a Sun Microsystems, em um dos maiores negócios do setor. Java como uma Tecnologia de Desenvolvimento de Software Algumas pessoas consideram que o Java não pode ser considerado apenas uma linguagem de programação, pois isto não daria a exata dimensão do que é a tecnologia. Essas pessoas dizem que o Java se compõe de três partes distintas: um ambiente de desenvolvimento, uma linguagem de programação e uma interface de programas aplicativos (API – Applications Programming Interface). O ambiente de desenvolvimento é composto pelo conjunto de ferramentas utilizadas para a construção de aplicativos. Esse conjunto é composto de: um compilador (javac), um interpretador (java), um visualizador de applets (appletviewer) e um gerador de documentação (javadoc). Existem ainda diversas IDE’s (Integrated Development Enviroment – Ambiente de Desenvolvimento Integrado), dentre os quais se destacam o NetBeans e o Eclipse. A linguagem de programação Java é composta por um conjunto de palavras e símbolos, utilizados pelos programadores para escrever seus programas. A linguagem Java é uma linguagem orientada a objetos, compilada, interpretada e independente de plataforma. 2 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Por fim, a API Java fornece uma série de ferramentas prontas para desenvolvimento, com uma vasta biblioteca de classes disponíveis ao programador para escrever seus programas. Ao se programar em Java, é importante ter em mente o lema: “não tente reinventar a roda” – não faz sentido codificar um programa se ele já foi feito. Ao invés disso, basta ajustar o que se tem pronto para os seus fins específicos. A Plataforma Java Uma plataforma é um conjunto de elementos que possibilitam a execução de aplicativos. A princípio, para rodar um aplicativo, é necessário apenas um computador com um sistema operacional instalado (por exemplo, o Windows, sendo chamado a plataforma Windows). Porém, os sistemas operacionais são concebidos para determinadas arquiteturas de computadores, sendo em geral incompatíveis com as demais (um programa escrito para Windows não é capaz de rodar em um computador com o Linux instalado). Na tecnologia Java um arquivo gerado pelo seu compilador pode ser executado em qualquer sistema operacional e, por conseguinte, em qualquer arquitetura de computador. Dessa forma, é possível escrever e compilar um programa em Java para depois executá-lo em qualquer plataforma. Isto é resumido em outro lema de Java: “Escreva uma vez, execute em qualquer lugar”. (Este lema é maliciosamente modificado para “Escreva uma vez, teste em todos os lugares”, devido a problemas ocorridos por rodar o aplicativo em plataformas diferentes). A figura abaixo ilustra o processo de criação e execução de programas em Java, fazendo um comparativo com o processo de criação e execução de programas em uma outra tecnologia tradicional (por exemplo, C/C++). 3 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Na tecnologia tradicional, os programas são compilados diretamente para o código binário, que é específico para o sistema operacional. Na tecnologia Java, os programas passam por um estágio intermediário: ele é compilado para bytecodes, que são padrão da tecnologia Java, e que podem ser lidos por uma Java Virtual Machine (JVM). A JVM é um interpretador desses bytecodes, traduzindo o programa para o código binário da máquina em tempo de execução. O uso da JVM faz com que o Java seja, essencialmente, uma linguagem interpretada. Existem JVM’s para diversos sistemas operacionais, até mesmo para diversos aparelhos (os celulares que rodam Java, por exemplo, possuem uma JVM). Em um ambiente Java típico, o programa passa por 5 fases distintas: 1. O programa é criado e armazenado em disco. 2. O programa é compilado, gerando arquivos com código intermediário (chamados bytecodes). 3. Ao ser executado, o interpretador Java (a Java Virtual Machine) é invocado e os bytecodes são colocados na memória. 4. Um verificador de bytecodes verifica se todas as instruções são válidas e se estas não violam restrições de segurança. 5. O interpretador lê os bytecodes e os converte para código binário específico para a plataforma atual. Note que para a execução de um programa em Java é necessária apenas a JVM instalada na máquina. A JVM faz parte do JRE – Java Runtime Enviroment (Ambiente de Execução Java), que está disponível na página oficial da Sun gratuitamente, para vários sistemas operacionais. O Primeiro programa em Java Para iniciar o estudoda linguagem Java, é importante ver o menor programa possível feito em Java – o clássico OláMundo. O código para este programa é visto abaixo: public class OlaMundo { public static void main(String[] args) { System.out.println(“Olá Mundo!”); } } Observe que o programa é ligeiramente maior que o mesmo programa feito em linguagem C. O programa contém também algumas palavras-chaves características do Java que talvez 4 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento não sejam familiares ao leitor. São elas: public, class, static e void. Antes de entender a estrutura da linguagem, entretanto, é importante que se saiba compilar o programa. Configurando o ambiente Java Para começar a programar em Java, é preciso fazer o download do J2SDK (Java 2 Standard Developer’s Kit) na página oficial da Sun [6] na referência bibliogáfica . Após instalar o J2SDK, entretanto, é preciso fazer algumas configurações que a instalação não faz automaticamente. Configurando o ambiente Java na Plataforma Windows No ambiente Windows XP/Vista siga os seguintes passos: 1. Dê um clique com o botão direito do mouse no ícone Meu Computador na área de trabalho, a caixa de diálogo Propriedades do Sistema abrirá, selecione a guia Avançado e clique no botão Variáveis de ambiente, conforme a figura baixo: 5 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Ao clicar no botão Variável de ambiente aparecerá a tela conforme a figura a seguir, dentro da caixa Variáveis do Sistema, selecione a varável PATH. 2. Clique no botão Editar. Isso fará com a caixa de diálogo Editar Variável do Sistema apareça conforme figura baixo: Posicione o cursor dentro do campo Variable value (Valor da Variável) e digite o caminho do diretório onde está o JDK seguido por \bin e clique no botão OK Essa última configuração é indispensável para que o compilador e o interpretador encontrem as bibliotecas de classes do Java. 6 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Configurando o ambiente Java na Plataforma Linux No Linux, é necessário configurar as mesmas variáveis, porém a forma de se fazer isso é um pouco diferente do Windows. Supondo que o J2SDK foi instalado no diretório /usr/java , é preciso proceder da seguinte maneira, colocando as linhas abaixo no arquivo ~/etc/profile: export JAVA_HOME=/usr/java/jdk1.5.0_06 export PATH=$PATH:$JAVA_HOME/bin export CLASSPATH=.:$JAVA_HOME/jre/lib O princípio na configuração dessas variáveis é o mesmo do Windows. Compilando um programa Java Após o ambiente ter sido configurado, é necessário compilar o programa. É necessário criar o código abaixo em um editor de texto padrão (o Bloco de Notas, no Windows, ou o vi, nano ou kwrite no Linux, por exemplo) e salvá-lo com o nome OlaMundo.java . public class OlaMundo { public static void main(String[] args) { System.out.println(“Olá Mundo!”); } } Para compilar o programa, deve-se proceder como (em um terminal do MS-DOS, ou em um terminal do Linux): javac OlaMundo.java Este comando deve criar o arquivo OlaMundo.class, que já é o seu programa Java, em bytecodes. Para executar o programa, deve-se chamar a JVM com o nome do seu programa: java OlaMundo O resultado, como já esperado, é: Olá Mundo! O desenvolvimento de um aplicativo em Java se resume à criação de fragmentos de códigos que se comunicam entre si, chamados classes e interfaces. O código do programa OlaMundo é composto de apenas uma classe, a classe pública OlaMundo. Qualquer arquivo contendo código-fonte Java pode ter no máximo uma classe pública, e ela deve ter o mesmo 7 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento nome que o arquivo onde está gravada (excetuando-se o .java). A classe OlaMundo deve ser salva em um arquivo chamado OlaMundo.java. O qualificador public define a condição da classe (pública) e a identificação da classe (class) é utilizado na declaração de novas classes. Método main() Em Java as classes são compostas por atributos e métodos. Os métodos são análogos às funções em C, realizam determinada tarefa a partir de alguns parâmetros, podendo retornar algum tipo de informação. Os atributos são análogos às variáveis globais em C – um atributo de classe é uma variável que está acessível para todos os métodos desta classe. Todo aplicativo é composto de uma ou mais classes, e pelo menos uma delas deve conter o método main(). A existência do método main() qualifica uma classe como executável – você pode chamar o programa a partir dela. Classes que não possuem o método main() podem ser utilizadas como componentes de outras classes, mas não podem ser executadas diretamente. Assim como em C, o primeiro método a ser executado em um programa Java é o método main() da classe que foi chamada. A assinatura do método main() é bastante importante para seu uso como ponto de partida do programa, embora alguns qualificadores só fiquem claros mais tarde, quando for visto a parte de Orientação a Objetos propriamente dita. A assinatura do método main() é: public static void main(String[] args) O primeiro qualificador define o método main() como público, enquanto o segundo qualificador define o método como estático. Esses dois conceitos são aplicados quando se trata de instanciação de objetos, e não serão discutidos aqui. Por enquanto, é importante saber apenas que o método main() deve ter os qualificadores public static. O terceiro qualificador, void, indica que o método main() não retorna nenhuma informação para quem o invocou. O qualificador void não pode ser omitido. O nome do método é importante: Java é case sensitive, diferenciando letras maiúsculas de minúsculas. 8 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Por fim, dentro dos parênteses estão os parâmetros do método main(). Neste caso, o método main() possui um argumento do tipo String[] (um array de strings) com o nome args. O nome do parâmetro não é importante aqui (poderia ser usado um outro nome, como argumentos, por exemplo, mas args é o padrão sugerido para facilidade de leitura), mas o tipo do argumento sim. Se o tipo de argumento fosse outro, por exemplo, int, este não seria o método chamado como ponto de partida da classe. Tipos de Dados Primitivos A característica de orientação a objetos (comumente abreviada como O.O.) da linguagem Java é muito forte. Em Java, todos os tipos de dados são objetos de determinadas classes – exceto um conjunto pequeno de dados chamados tipos primitivos. Esses dados funcionam de maneira similar que os dados na Linguagem C, porém com uma diferença: em Java, eles não dependem do tamanho da palavra do processador da máquina. O tamanho e a forma de armazenamento dos tipos primitivos é a mesma em qualquer JVM. Em Java, existe 4 tipos primitivos para armazenamento de números inteiros, dois tipos primitivos para armazenamento de números em ponto flutuante, um para caracteres e um último para valores booleanos. Dados compostos por cadeias de caracteres (strings) são um objeto da classe String existente na API do Java – eles serão abordados em um momento posterior. A diferença básica entre um tipo primitivo e uma classe é que o primeiro armazena apenas uma única informação – seu valor – enquanto o segundo pode armazenar várias informações em seus atributos e realizar tarefas através de seus métodos. Números Inteiros Existem 4 opções para representar números inteiros em Java, diferenciando apenas a capacidade de armazenamento de cada tipo de dado. Atabela abaixo exemplifica esses tipos: Tipo Tamanho Mínimo Máximo byte 1 byte (8 bits) -128 127 short 2 bytes (16 bits) -32.768 32.767 int 4 bytes (32 bits) -2.147.483.648 2.147.483.647 long 8 bytes (64 bits) -9.223.372.036.854.775.808 9.223.372.036.854. 775.807 9 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento A coluna tamanho indica a quantidade de memória ocupada por cada um dos tipos primitivos. Note que o alcance do número mínimo é maior que o alcance do número máximo – isso porque o Java representa os números inteiros negativos como tendo o bit mais significativo com valor negativo. O tipo int é o tipo mais adequado para a maioria das situações. Seu alcance é suficiente para a maioria das aplicações e é o tipo padrão usado pelo Java. Se o programa necessitar de uma representação numérica mais abrangente, pode ser usado o tipo long. Os tipos byte e short são utilizados principalmente em aplicações que necessitam de grandes quantidades de dados, como uma forma de manipular a memória utilizada mais eficiente. Vejamos alguns exemplos do uso dos tipos inteiros, como sua declaração e inicialização: public class Exemplo { public static void main(String[] args) { int numero_32bits; byte numero 8bits; numero 32bits = 327; numero 8bits = 120; } } Na linha 5 é declarada a variável numero_32bits, como sendo do tipo int. Na linha 6, é declarada a variável numero_8bits como sendo do tipo byte. A inicialização é feita nas linhas 7 e 8, respectivamente. A forma como é feita a declaração e inicializaão é bastante similar ao C. São possíveis também as seguintes formas: public class Exemplo { public static void main(String[] args) { int a, b, c; byte d = 87; } } Na linha 5, três variáveis são declaradas ao mesmo tempo, enquanto que na linha 6 a variável é declarada e inicializada. O próximo exemplo mostra um resultado diferente: public class Exemplo { public static void main(String[] args) { 10 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento int a = 145; byte b = a; } } O programa mostrado acima não irá compilar. O compilador irá abortar a compilação reportando um erro de possible loss of precision (possível perda de precisão). Isso acontece porque o Java protege suas variáveis para que não ocorra overflow (estouro).O erro do compilador é o seguinte: C:\Exemplo\Exemplo.java:5: possible loss of precision found : int required: byte byte b = a; A saída de erro do compilador pode ser interpretada como: na linha 5 ocorre uma possível perda de precisão, pois na declaração “byte b = a;” era esperado um valor do tipo byte e foi encontrado um valor do tipo inteiro. Isso porque o número inteiro de 32 bits não cabe no byte de 8 bits, e o Java não altera o tipo da variável automaticamente. O número 145 realmente é maior que a capacidade de um byte, porém o exemplo falha na compilação mesmo se fosse usado um número menor, como 87, por exemplo. Para que o exemplo compile, é preciso fazer um cast na linha 6. public class Exemplo { public static void main(String[] args) { int a = 145; byte b = (byte) a; } } O cast (conversão) da linha 6, representado pela palavra (byte) indica ao Java que, antes de colocar o valor da variável a na variável b, é preciso fazer uma conversão de tipo. É preciso ter atenção a esta conversão: ela é feita pegando apenas os 8 bits menos significativos do inteiro e atribuindo ao byte. Neste caso, temos: Int (32 bits) Byte (8 bits) Binário Decimal Binário Decimal 00000000000000000000000010010001 145 10010001 -111 Note que o bit mais significativo de uma variável inteira tem valor negativo. O cast é a maneira de você dizer ao compilador: eu sei que pode ocorrer uma perda de precisão, mas 11 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento eu sou o programador e sei o que estou fazendo. Note também que não ocorre um erro: o comportamento da linguagem diante desta situação é bem especificado, é preciso apenas saber como será esse comportamento. Os próximos dois exemplos ilustram o cast em outra situação. public class Exemplo { public static void main(String[] args) { int a = 7; int b = 8; int c = a + b; } } O valor da variável c ao final da execução será: 7 + 8 = 15, sem surpresas. Entretanto: public class Exemplo { public static void main(String[] args) { byte a = 7; byte b = 8; byte c = a + b; } } Resulta em um erro de compilação. O motivo para isto é que, no momento do cálculo da soma, as variáveis a e b são convertidas para inteiros de 32 bits, para aumentar a precisão da soma. Assim, o número a + b é um inteiro de 32 bits, e não um byte de 8 bits, não podendo ser armazenado em uma variável do tipo byte. Para que o código compile, existem duas saídas: byte c = (byte) a + b; Fazer o cast do inteiro de 32 bits a + b para um byte (note que aqui podem haver erros de precisão, exatamente da mesma forma que a anterior) ou: int c = a + b; Armazenar o resultado em um inteiro. A maneira mais adequada depende da situação. Números de Ponto Flutuante Os números de ponto flutuante representam os números reais. O Java oferece dois tipos de números de ponto flutuante: float e double. A tabela abaixo exemplifica os dois: 12 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Tipo Tamanho Mínimo Máximo Precisão float 4 bytes (32 bits) -3.4028E+38 3.4028E+38 6-7 dígitos double 8 bytes (64 bits) -1.7976E+308 1.7976E+308 15 dígitos O tipo float não é muito utilizado – o padrão para números de ponto flutuante em Java é o double. Para representar um número no formato float, deve-se acrescentar a ele um f no final. public class Exemplo { public static void main(String[] args) { float a = 2.5; } } O programa acima não compila – ele exige um cast do número 2.5 (que para o Java é do tipo double). Para que o programa compile, é necessário fazer o cast explícito, ou colocar a letra f no final. float a = (float) 2.5; float a = 2.5f; Caractere A representação de um único caractere é feita pelo tipo primitivo char, enquanto a representação de cadeias de caracteres é feita pela classe String. No momento, vamos nos ater ao tipo primitivo char. O tipo char é o único inteiro sem sinal em Java. A tabela abaixo resume as características do char. Tipo Tamanho Mínimo Máximo char 2 byte (16 bits) 0 65535 Enquanto em C o tipo char representa os valores da tabela ASCII, em Java o tipo char representa os valores da tabela Unicode. A tabela Unicode é um padrão feito para representar caracteres que engloba vários idiomas, e não apenas os idiomas que usam o alfabeto latino. 13 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Tipo Lógico O último tipo primitivo em Java é o tipo lógico boolean. A tabela abaixo mostra os valores que a variável do tipo boolean pode assumir: Boolean true False Ao contrário da linguagem C, onde um inteiro é considerado como falso se seu valor for 0 e verdadeiro caso contrário, em Java não existe conversão de tipos lógicos para tipos numéricos. Conversões (CAST) As conversões, ou casts, já foram falados anteriormente. Entretanto, o Java pode fazer casts implícitos quando não há risco de perda de precisão. Os casts implícitos feitos em Java estão resumidos nas linha abaixo: byte -> short -> int -> long -> float -> double char -> int Quando se anda da esquerda para a direita na tabela, não é necessário explicitar o cast – oJava faz isso automaticamente (isto é, se você quiser atribuir um valor de uma variável int a uma variável long, não é necessário explicitar o cast). Entretanto, quando se anda da direita para a esquerda o cast deve ser explicitado, ou o código não irá compilar. public class Exemplo { public static void main(String[] args) { long a = 43, b = 75; int c = (int) (a + b); float d = 3.7f, e = 4.6f; float f = d + e; char ch = 'A'; int g = ch; System.out.println("c = " + c + "\nf = " + f + "\ng = " + g); } } A saída do exemplo acima será: c = 118 14 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento f = 8.3 g = 65 Note que não é necessário fazer o cast explícito quando se somam dois floats. Operadores Os operadores são caracteres especiais utilizados para realizar determinadas operações com um ou mais operandos. Nos exemplos acima já vimos alguns operadores: os operadores de soma e atribuição. A operação é determinada pelo tipo de operador utilizado e os operandos assumem o papel de argumentos na operação, podendo ser valores literais, variáveis, constantes ou expressões. Em Java, os operandos podem modificar a forma como a operação é executada – a isso se chama de sobrecarga de operadores. Os operadores podem ser classificados como unários (realizam operações em um único operando), binários (realizam operações com dois operandos) e ternários (realizam operações em três operandos). Outra classificação, que será usada aqui, é a classificação por tipo de operação – neste caso, os operadores podem ser classificados em aritméticos, relacionais e lógicos. Operadores Aritméticos Os operadores aritméticos são utilizados para a realização de operações matemáticas com operandos do tipo numéricos. A tabela abaixo relaciona os operadores disponíveis em Java. Operador Função + Adição - Subtração * Multiplicação / Divisão % Módulo (Resto da Divisão) ++ Incremento -- Decremento += Atribuição Aditiva -= Atribuição Subtrativa *= Atribuição de Multiplicação /= Atribuição de Divisão %= Atribuição de Módulo 15 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Os operadores aritméticos não podem ser utilizados com operandos do tipo boolean ou com textos (Strings), porém podem ser aplicados com caracteres (char), uma vez que este é um subconjunto dos números inteiros. Os operadores de adição, subtração, multiplicação e divisão funcionam da mesma forma que em matemática – somam, subtraem, multiplicam ou dividem os operandos. O operador de módulo é utilizado para obter o resto da divisão de dois operandos, não importando se os operandos são números inteiros ou de ponto flutuante. Por exemplo: int it = 9 % 2; double db = 8.5 % 3.2; Resulta em: it = 1 db = 2.0999999999999996 Na primeira linha, o número 9 representa o dividendo da operação e o número 2 o divisor. O quociente será 4 e o resto será 1, que é o retorno do operador %. Os operadores de incremento e decremento são aplicados sobre um único operando e servem para aumentar ou reduzir seu valor em 1 unidade. A controvérsia gerada por estes operadores é ilustrada nos exemplos abaixo: int a = 5; int b = a++; int a = 5; int b = ++a; Nos dois exemplos, cria-se uma variável a e atribui-se a ela o valor 5. No primeiro exemplo, o operador ++ aparece depois da variável a, enquanto no segundo exemplo ele aparece antes da variável a. O resultado final da expressão é o mesmo – o valor de a é incrementado de uma unidade, passando a ter o valor 6. A chave de questão é quando o valor de a é incrementado. No primeiro exemplo, atribui-se à variável b o valor corrente de a e depois incrementa-se a. No segundo exemplo, incrementa-se a e depois atribui-se o valor de a a variável b. O resultado dos dois exemplos é: a = 6 b = 5 a = 6 16 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento b = 6 O operador de decremento funciona da mesma maneira. O restante dos operadores são os operadores de atribuição. Sua funcionalidade é simples de entender através de um exemplo: int a = 9; a += 9; é o mesmo que escrever: int a = 9; a = a + 9; Ou seja, ele soma seu próprio valor ao valor do operando ao qual está agindo. O mesmo raciocínio é válido para os demais operadores de atribuição. Operadores Relacionais Os operadores relacionais são utilizados para comparar igualdade e a ordem entre valores literais, variáveis, constantes e expressões. Todas as operações realizadas com esse tipo de operadores envolvem dois operandos e retornam um valor lógico true (verdadeiro) ou false (falso). A tabela abaixo resume os operadores relacionais. Operador Função = = Igual a != Diferente de > Maior que < Menor que >= Maior ou igual a <= Menor ou igual a Os operadores de igualdade (= =) e desigualdade (!=) podem ser aplicados para comparar valores de quaisquer tipos primitivos (byte, short, int, long, float, double, char e boolean). Considere o exemplo abaixo: public class OperadoresRelacionais { public static void main(String[] args) { 17 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento int a = 10; long b = 12; byte c = 10; boolean b1 = (a == b); boolean b2 = (a == c); boolean b3 = (a != b); System.out.println("a == b : " + b1); System.out.println("a == c : " + b2); System.out.println("a != b : " + b3); } } A saída do programa será: a == b : false a == c : true a != b : true Note que os operadores comparam os valores das variáveis – não consideram o tipo delas. No exemplo, a variável a é um inteiro com valor 10, enquanto a variável c é um byte com valor 10, e elas são consideradas iguais pelo operador de igualdade (= =). Os operadores de igualdade e desigualdade não devem ser usados para comparar objetos. Embora os conceitos do porque isso não deve ser feito ainda não vão ficar totalmente claros, o exemplo abaixo irá ilustrar que o uso desses operadores com objetos pode retornar valores diferentes do que seria esperado. public class OperadoresRelacionais { public static void main(String[] args) { String st1 = new String("abc"); String st2 = new String("abc"); boolean b = (st1 == st2); System.out.println("st1 == st2 : " + b); } } A saída deste programa será: st1 == st2 : false O que ocorre neste caso é que st1 e st2 são dois objetos diferentes. A comparação com o operador de igualdade nesse caso compara se os dois objetos estão ocupando o mesmo endereço na memória, o que não é o caso, uma vez que são dois objetos diferentes. 18 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Portanto, a comparação retorna falso. Se o programa fosse estruturado de maneira um pouco diferente: public class OperadoresRelacionais { public static void main(String[] args) { String st1 = "abc"; String st2 = "abc"; boolean b = (st1 == st2); System.out.println("st1 == st2 : " + b); } } A saída seria diferente: st1 == st2 : true Neste caso, o que ocorre é que o compilador não cria dois objetos de String – como ele vê que os dois tem o mesmo conteúdo, ele cria um único objeto e duas referências para ele, st1 e st2. Por isso, quando o operador de igualdade compara a posição na memória dos dois objetos, ele retorna verdadeiro. A maneira correta para se comparar o conteúdo de duas Strings é utilizando o método equals() da classe String: public class OperadoresRelacionais { public static voidmain(String[] args) { String st1 = new String("abc"); String st2 = new String("abc"); boolean b = st1.equals(st2); System.out.println("st1 == st2 : " + b); } } Neste caso, a saída do programa será: st1 == st2 : true O método equals() compara o conteúdo das duas strings, e não suas posições na memória. 19 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Os demais operadores relacionais (maior que, menor que, maior ou igual a e menor ou igual a) só podem ser utilizados com tipos numéricos (byte, short, int, long, float, double e char). O exemplo abaixo ilustra o uso desses operadores: public class OperadoresAritmeticos { public static void main(String[] args) { byte a = 25; int b = 25; long c = -37; boolean b1 = (a > b); boolean b2 = (a >= b); boolean b3 = (a > c); System.out.println("a > b :" + b1); System.out.println("a >= b :" + b2); System.out.println("a > c :" + b3); } } O resultado deste programa será: a > b :false a >= b :true a > c :true Uma vez a não é menor do que b (eles são iguais), a é maior ou igual a b e a é maior do que c (uma vez que c é negativo e a positivo). Operadores Lógicos Os operadores lógicos são utilizados para construir expressões que retornam um resultado booleano. Com exceção dos operadores if-then-else ternário e NOT unário, todos os demais envolvem dois operandos, que podem ser valores literais, variáveis, constantes ou expressões que resultem em um valor booleano. Talvez seja difícil entender porque existem tais operadores – isso ficará mais claro mais tarde, quando for visto estruturas de decisão e repetição. A tabela abaixo lista os operadores lógicos: Operador Função | OR lógico || OR dinâmico 20 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento & AND lógico && AND dinâmico ^ XOR lógico ! NOT unário lógico |= Atribuição de OR &= Atribuição de AND ^= Atribuição de XOR ?: if-then-else ternário Os operadores OR e AND funcionam segundo a tabela verdade abaixo: X Y X OR Y X AND Y false false false false false true true false true false true false true true true true O exemplo abaixo ilustra o uso dos operadores OR e AND lógicos. public class OperadoresLogicos { public static void main(String[] args) { boolean x = true; boolean y = false; boolean z = true; boolean b1 = x & y; boolean b2 = x & z; boolean b3 = x | y; System.out.println("x & y : " + b1); System.out.println("x & z : " + b2); System.out.println("x | y : " + b3); } } A saída deste programa será: x & y : false x & z : true x | y : true Na operação OR, o resultado será true se pelo menos um dos operandos for true, enquanto na operação AND o resultado será false se pelo menos um dos operandos for false. A 21 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento diferença do OR e AND lógicos para os operadores OR e AND dinâmicos é que, nos últimos, ele pode não contabilizar o segundo operando, dependendo do primeiro operando. Por exemplo: boolean x = true; boolean y = false; boolean z = x || y; Na avaliação da expressão da linha 4, sabe-se que o resultado será true assim que avalia-se o primeiro operando, x, e verifica-se que este é true. Uma vez que o primeiro operando é true¸ não importa qual será o segundo operando, o resultado será true. Assim, o segundo operando não é avaliado. Deve-se tomar cuidado, entretanto, pois caso o segundo operando venha a conter alguma atribuição, ela não será executada. O operador XOR funciona segundo a tabela abaixo. X Y X XOR Y false false false false true true true false true true true false O operador XOR retornará true se os dois operandos forem diferentes, e retornará false se os dois operandos forem iguais. O operador NOT unário inverte o valor do operando: X NOT X false true true false Os três operandos de atribuição funcionam de maneira similar aos operandos de atribuição aritméticos. Por exemplo: boolean x = true; boolean y = false; x |= y; equivale a: 22 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento boolean x = true; boolean y = false; x = x | y; O operador if-then-else ternário (?:) é uma estrutura de seleção. Sua sintaxe é: <expressão> ? <declaração1> : <declaração2> Deve-se utilizar uma expressão que resulte em um valor booleano. O retorno dessa estrutura é a declaração1, se a expressão for true, ou a declaração2, se a expressão for false. Um exemplo de uso: int a = 10, b = 5; int c = (a == 0) ? 0 : (a/b); Neste caso, como (a = = 0) é false, o resultado atribuído a c é o resultado da expressão a/b, ou seja, 2. Neste outro caso: int a = 0, b = 5; int c = (a == 0) ? 0 : (a/b); Como (a = = 0) é true, o resultado atribuído a c é 0. Precedência de Operadores Para resolver expressões algébricas, é preciso obedecer a uma certa ordem. Primeiro, calcula-se as partes que estão delimitadas por parênteses, depois calculam-se as multiplicações antes de se calcular as adições e subtrações. Este raciocínio existe em Java: a tabela de precedência de operadores é mostrada aseguir. ( ) [ ] . ++ - - ! * / % + - 23 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento > >= < <= = = != & ^ | && || ?: = Cada uma das linhas da tabela representa um nível de precedência, e os elementos de uma mesma linha tem a mesma precedência. Para ilustrar este conceito, vamos analisar alguns exemplos: int a = 5; int b = 2 + 2 * 7 – 4 / --a; A primeira instrução declara a variável a. A segunda instrução atribui a variável b o resultado de uma expressão composta por 5 operações distintas: adição, multiplicação, subtração, divisão e decremento. Para saber como essa expressão será avaliada para extrair seu resultado, observe a ordem de precedência dos operadores. O operador de maior precedência é o operador de decremento (- -) – ele será avaliado primeiro. Assim, a expressão agora fica: b = 2 + 2 * 7 – 4 / 4; Em seguida, os operadores de maior prioridade são os operadores de multiplicação e divisão, que tem a mesma prioridade. Entretanto, como o de multiplicação está mais à esquerda, ele é avaliado primeiro. Assim, temos: b = 2 + 14 – 4 / 4; Em seguida, avalia-se o operador de divisão: 24 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento b = 2 + 14 – 1; Por fim, os operadores de adição e subtração tem a mesma precedência, mas como a soma está mais à esquerda, ela é calculada primeiro: b = 16 - 1; b = 15; Para que as operações de adição e subtração sejam calculadas primeiro, elas deveriam ser colocadas entre parênteses. Veja este exemplo: int a = 5; int b = (2 + 2) * (7 – 4) / --a; Neste caso, o cálculo ocorre da seguinte maneira: b = (2 + 2) * (7 – 4) / --a; b = 4 * (7 – 4) / --a; b = 4 * 3 / --a; b = 4 * 3 / 4 ; b = 12 / 4 ; b = 3; Estruturas de Decisão As estruturas de decisão são utilizadas para controlar o fluxo de execução dos programas, possibilitando que a leitura das instruções siga caminhos alternativos em função do estado de dados booleanos. Com elas, é possível condicionar a execução de uma ou mais instruções a uma ou mais condições que precisam ser satisfeitas. Existem três estruturas de decisão disponíveis na linguagem Java disponíveis em Java: a estrutura if, a estrutura if-else e a estrutura switch-case. A Estruturaif Esta estrutura de decisão é utilizada para impor uma ou mais condições que deverão ser satisfeitas para a execução de uma instrução ou bloco de instruções. A sua forma geral é: if (<condição>) <instrução ou bloco de instruções> 25 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento A condição deverá estar entre parênteses após a palavra if, e deverá ser sempre uma expressão booleana. As instruções a seguir somente serão executadas caso o valor dessa condição seja true. Se houver uma única instrução condicionada pela estrutura if, ela pode figurar logo após a condição e deve terminar com um ponto-e-vírgula. A sintaxe é a seguinte: if (<condição>) <instrução>; Observe o exemplo abaixo (considere que as variáveis inteiras a, b e c já foram inicializadas). if (b!=0) c = a/b; Neste exemplo, se a condição for true (isto é, se b for diferente de 0), a instrução c = a/b será executada. Em seguida, o programa continuará com seu fluxo de execução normal, executando a instrução logo abaixo do if. Para condicionar a execução de um bloco de instruções, é preciso delimitá-lo com o uso de chaves. A sintaxe, neste caso, é a seguinte: if (<condição>) { <instrução 1>; <instrução 2>; ... <instrução n>; } Observe que a estrutura if não tem um ponto-e-vírgula para finalizá-la. Um exemplo de condicionamento de um bloco de instruções: if (b!=0) { c = a/b; System.out.println(“A resposta é “ + c + “ .”); } A Classe JOptionPane A classe JOptionPane pertence ao pacote javax.swing e oferece uma maneira simples de se fazer caixas de diálogo em Java. Estas caixas de diálogo podem ser informativas ou 26 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento utilizadas para receber algum parâmetro. No exemplo veremos como utilizar a classe JOptionPane. import javax.swing.JOptionPane; public class JOptionPaneExemplo { public static void main(String[] args) { String st = JOptionPane.showInputDialog(null,"Informe seu nome:"); JOptionPane.showMessageDialog(null,"Seu nome é: " + st); System.exit(0); } } Para utilizar a classe JOptionPane, é preciso importá-la (isto é, dizer ao compilador que você irá utilizar essa classe). Isso é feito na primeira linha, antes da declaração da classe. O uso que iremos dar para essa classe é bastante simples, e não iremos nos preocupar com os detalhes neste momento. Na primeira instrução da função main(), temos: String st = JOptionPane.showInputDialog(null,"Informe seu nome:"); Que é uma chamada ao método showInputDialog() da classe JOptionPane. Este método retorna um objeto do tipo String, recebido na variável st. O método showInputDialog() tem dois argumentos: para o primeiro é passado a referência null e, no segundo, um objeto String. O resultado é uma caixa de diálogo de entrada, que irá capturar o que for escrito e colocar no objeto st. Na segunda instrução, temos: JOptionPane.showMessageDialog(null,"Seu nome é: " + st); Que é uma chamada ao método showMessageDialog(), que simplesmente fornece uma caixa de diálogo. O primeiro parâmetro é novamente a referência null e o segundo parâmetro a string que será exibida na tela. A última linha, System.exit(0); Deve ser usada sempre que se usa componentes do pacote Swing, indicando a JVM para fechar estes objetos. O resultado deste código é: 27 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Onde a primeira caixa de diálogo é a caixa de entrada, com o nome Input, e o segundo é a caixa de mensagem, com o nome Message. O programa descrito no último exemplo tem dois detalhes: O usuário pode apertar Cancel, ao invés de OK, na caixa de diálogo de entrada. Se isso acontecer, é passada à variável st a referência null e, na caixa de mensagem, irá aparecer a mensagem: Seu nome é: null. Este é o mesmo efeito de se apertar o botão x, para fechar a caixa de diálogo. O segundo detalhe é que o usuário poderia não digitar nada, apenas pressionar OK. Neste caso, é passada à variável st uma string vazia e a mensagem na caixa de diálogo seria: Seu nome é:. Para proteger o programa destes dois detalhes, poderíamos utilizar a estrutura de decisão if: import javax.swing.JOptionPane; public class JOptionPaneExemplo { public static void main(String[] args) { String st = JOptionPane.showInputDialog(null,"Informe seu nome:"); if (st == null) System.exit(0); if (st.length() == 0) System.exit(0); JOptionPane.showMessageDialog(null,"Seu nome é: " + st); System.exit(0); } } Dessa forma, se um dos casos acima ocorrer, o programa terminará antes de aparecer a última caixa de diálogo. 28 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Note que na terceira linha o método main() ocorre uma chamada ao método st.length(). O método length() é um método da classe String que retorna o número de caracteres presente na String, e só pode ser utilizado se o objeto tiver sido criado. Se invertêssemos as duas condições do programa acima, como no exemplo abaixo: import javax.swing.JOptionPane; public class JOptionPaneExemplo { public static void main(String[] args) { String st = JOptionPane.showInputDialog(null,"Informe seu nome:"); if (st.length() == 0) System.exit(0); if (st == null) System.exit(0); JOptionPane.showMessageDialog(null,"Seu nome é: " + st); System.exit(0); } } E apertássemos Cancel ao invés de OK, o programa seria fechado por causa de um erro: uma NullPointerException será lançada, pois a variável st não é uma referência para nenhum objeto (é uma referência a null) e estamos tentando executar um método nesta referência. Não se preocupe muito sobre exceções e tratamento de exceções no momento – este será o assunto para uma aula futura. Considere agora o seguinte programa: import javax.swing.JOptionPane; public class JOptionPaneExemplo { public static void main(String[] args) { String st; st = JOptionPane.showInputDialog(null,"Digite o primeiro número:"); int a = Integer.parseInt(st); st = JOptionPane.showInputDialog(null,"Digite o segundo número:"); int b = Integer.parseInt(st); int c = a/b; JOptionPane.showMessageDialog(null,"a/b = " + c); System.exit(0); } } O resultado deste programa será: 29 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Este programa utiliza o método parseInt() da classe Integer para transformar um string em um tipo primitivo int. Note que o argumento 10, passado à caixa de diálogo, é uma string, e para fazer a divisão precisamos de um número. A instrução: int a = Integer.parseInt(st); Faz a transformação da string st para o tipo inteiro a. Observe que este programa contém alguns erros, que não foram tratados e que podem resultar em um problema na hora da execução: a string digitada na caixa de diálogo pode não ser uma string numérica (poderia ter sido digitado “abc”, por exemplo), ou o usuário poderia ter apertado Cancel ou x para fechar a caixa de diálogo. Nos dois casos, teremos um erro de NumberFormatException. Não iremos nos ater a isto no momento, apenas passaremos adiante para tratar do outro erro que pode acontecer no programa: o segundo número digitado pode ser o número 0 (zero). Se isto acontecer, o programa também abortará, mostrando um erro de ArithmeticException: / by zero (divisão por zero). Este erro é facilmente tratado por uma condição if. Veja o exemplo: import javax.swing.JOptionPane; public classJOptionPaneExemplo 30 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento { public static void main(String[] args) { String st; st = JOptionPane.showInputDialog(null,"Digite o primeiro número:"); int a = Integer.parseInt(st); st = JOptionPane.showInputDialog(null,"Digite o segundo número:"); int b = Integer.parseInt(st); if (b == 0) { JOptionPane.showMessageDialog(null,"Erro: Não se pode dividir por zero."); System.exit(0); } int c = a/b; JOptionPane.showMessageDialog(null,"a/b = " + c); System.exit(0); } } Neste caso, temos um bloco de instruções condicionado à expressão (b == 0). Se o usuário digitar 0 (zero) para o segundo número, a expressão será verdadeira, desviando o fluxo para a mensagem de erro. Note que o System.exit(0) força o fim do programa, e portanto as últimas linhas não serão executadas. A Estrutura if-else A estrutura de decisão if-else é uma variação da estrutura if. Ela é utilizada para impor uma ou mais condições que deverão ser satisfeitas para a execução de uma instrução ou bloco de instruções, e possibilita a definição de uma instrução ou bloco de instruções caso ela não seja satisfeita. A forma geral é: if (<condição>) <instrução ou bloco> else <instrução ou bloco> As mesmas regras aplicadas à condição na estrutura if se aplicam aqui e a estrutura será mostrada através de um exemplo simples: public class Exemplo { public static void main(String[] args) { double nota1 = 8; double nota2 = 7; double media = (nota1 + nota2)/2; if (media > 7) System.out.println("Você foi aprovado."); else 31 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento System.out.println("Você foi reprovado."); } } Neste exemplo, como a media é maior que 7, a primeira instrução é mostrada na tela. Outro exemplo, utilizando agora blocos de instruções: public class Exemplo { public static void main(String[] args) { double nota1 = 8; double nota2 = 7; double media = (nota1 + nota2)/2; if (media > 7) { System.out.println("Você foi aprovado."); System.out.println("Parabéns!"); } else { System.out.println("Você foi reprovado."); System.out.println("Boa sorte na prova de recuperação."); } } } Também é possível fazer a estrutura if-else if – else. Veja o exemplo: public class Exemplo { public static void main(String[] args) { double nota1 = 6; double nota2 = 7; double media = (nota1 + nota2)/2; if (media > 7) { System.out.println("Você foi aprovado."); System.out.println("Parabéns!"); } else if (media > 5) { System.out.println("Você nao foi aprovado."); System.out.println("Boa sorte na prova de recuperação."); } else { System.out.println("Você foi reprovado."); } } } Note que ele irá executar apenas um dos blocos de código encontrados nessa estrutura. A Estrutura switch-case 32 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento A estrutura de decisão switch-case fornece uma maneira simples para se definir diversos desvios no código a partir de uma única variável ou expressão. Havendo uma variável com diversos valores possíveis e sendo necessário um tratamento específico para cada um deles, o uso da estrutura if-else se torna confuso e dificulta a leitura do código. A sintaxe geral da estrutura switch é: switch (<expressão ou variável>) { case <valor1>: <instrução 1>; break; case <valor2>: <instrução 2>; break; case <valorN>: <instrução N>; break; default: <instrução default>; } Se for utilizada uma expressão, ela deve retornar um tipo de dado compatível com todos os valores especificados através das declarações case. Cada um dos valores especificados com a declaração case deve ser um valor literal exclusivo. Se houver algum valor duplicado, será gerado um erro de compilação (duplicate case label). public class Exemplo { public static void main(String[] args) { int a = 2; switch (a) { case 0: System.out.println("Zero."); break; case 1: System.out.println("Um."); break; case 2: System.out.println("Dois."); break; default: System.out.println("Mais de Dois (ou menos de Zero)."); } System.out.println(“Fim do Programa.”); } } No exemplo acima, aparecerá na tela somente: 33 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Dois. Fim do Programa. A palavra reservada break é utilizada na estrutura switch para promover um desvio da execução para a linha posterior ao final de seu bloco. Normalmente ele é utilizado no final de cada expressão case. Seu uso não é obrigatório, mas caso ele não esteja presente, o programa executa todas as linhas após o case correto até encontrar o próximo break. Por exemplo: public class Exemplo { public static void main(String[] args) { int a = 1; switch (a) { case 0: System.out.println("Zero."); case 1: System.out.println("Um."); case 2: System.out.println("Dois."); default: System.out.println("Mais de Dois (ou menos de Zero)."); } System.out.println(“Fim do Programa.”); } } Irá resultar em: Um. Dois. Mais de Dois (ou menos de Zero). Fim do Programa. Observe que a instrução referente ao case 0 não foi executada, pois ela se encontrava antes do case 1. Os valores dos cases não precisam estar em ordem – se o case 0 estivesse depois do case 1 no último exemplo, ele seria executado. O bloco default irá ser executado se nenhuma das opções for a correta. Ele não precisa estar no final das opções, porém, se não estiver, irá precisar da instrução break para que as demais instruções não sejam executadas. Estruturas de Repetição 34 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento As estruturas de repetição, também conhecidas como laços ou loops, são utilizadas para executar repetidamente uma instrução ou bloco de instruções enquanto determinada condição estiver sendo satisfeita. Qualquer que seja a estrutura de repetição, ela conterá quatro elementos fundamentais: inicialização, condição, corpo e iteração. A inicialização compõe-se de todo código que determina a condição inicial dos elementos envolvidos no laço. A condição é uma expressão booleana avaliada após cada leitura do corpo e determina se uma nova leituradeve ser feita ou se o laço deve ser encerrado. O corpo compõe-se de todas as instruções que são executadas repetidamente. A iteração é a instrução que deve ser executada depois do corpo e antes de uma nova repetição. Existem três tipos distintos de laços em Java, e cada um deles é útil para realizar tipos distintos de repetições. São eles: while, do-while e for. Estrutura while O laço while é usado para executar repetidamente uma instrução ou bloco de instruções enquanto uma expressão booleana for verdadeira. A sintaxe do laço while é a seguinte: <inicialização> while(<condição>) <corpo> <iteração> O exemplo abaixo ilustra o uso do laço while. public class ExemploWhile { public static void main(String[] args) { int a = 0; while (a < 5) System.out.println(++a); } } A saída deste código é: 1 2 3 4 35 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento 5 Outro exemplo interessante: public class ExemploWhile { public static void main(String[] args) { int a = 70; while (a >= 65) { String st = "O número " + a + " equivale ao caractere " + (char)a + " ."; System.out.println(st); a--; } } } A saída deste código é: O número 70 equivale ao caractere F . O número 69 equivale ao caractere E . O número 68 equivale ao caractere D . O número 67 equivale ao caractere C . O número 66 equivale ao caractere B . O número 65 equivale ao caractere A . Observe que, se a condição for falsa antes do início do laço, o laço não é executado, como no exemplo: public class ExemploWhile { public static void main(String[] args) { boolean condicao = false; while (condicao) { System.out.println("Entrei no while."); condicao = false; } } } Este programa não produzirá saída nenhuma. Outro ponto crítico em que se deve prestar atenção: a iteração deve fornecer uma forma da condição ser falsa, caso contrário, o programa entrará em um loop infinito. Estrutura do-while 36 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento A estrutura do-while é uma variação da estrutura while, com uma variação: a condição é avaliada no final, fazendo com que o laço seja executado pelo menos uma vez, mesmo que a condição seja inicialmente falsa. A sintaxe do laço do-while é a seguinte: <inicialização> do <corpo> <iteração> while (<condição>) O exemplo abaixo ilustra a principal diferença entre os laços while e do-while. public class ExemploDoWhile { public static void main(String[] args) { boolean condicao = false; do { System.out.println("Entrei no do-while."); condicao = false; } while (condicao); } } A saída deste programa será: Entrei no do-while. Estrutura for O laço for é uma estrutura de repetição compacta. Seus elementos de inicialização, condição e iteração são reunidos em forma de um cabeçalho e o corpo é disposto em seguida. A sintaxe geral de uma estrutura for é: for (<inicialização>:<condição>:<iteração>) <corpo> Um exemplo de uso do laço for é dado abaixo: public class ExemploFor { public static void main(String[] args) { int a; for (a = 70 ; a >= 65 ; a--) { 37 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento String st = "O número " + a + " equivale ao caractere " + (char)a + " ."; System.out.println(st); } } } A saída do programa será: O número 70 equivale ao caractere F . O número 69 equivale ao caractere E . O número 68 equivale ao caractere D . O número 67 equivale ao caractere C . O número 66 equivale ao caractere B . O número 65 equivale ao caractere A . O laço for oferece também a opção de declarar a variável dentro da inicialização. Porém, se isto for feito, o escopo da variável será apenas dentro do laço for. public class ExemploFor { public static void main(String[] args) { for (int a = 70 ; a >= 65 ; a--) { String st = "O número " + a + " equivale ao caractere " + (char)a + " ."; System.out.println(st); } } } Este exemplo irá gerar a mesma saída do exemplo anterior. Quebras de Laço As quebras de laço são utilizadas para interromper o fluxo normal das estruturas de repetição while, do-while e for. Existem dois tipos distintos de quebras de laço, representadas pelas palavras break e continue. O exemplo abaixo ilustra o uso da palavra break. import javax.swing.JOptionPane; public class ExemploBreak { public static void main(String[] args) { String st; while (true) { st = JOptionPane.showInputDialog(null,"Digite seu nome: "); if (st == null) System.exit(0); if (!st.equals("")) break; 38 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento } JOptionPane.showMessageDialog(null,"Seu nome é: " + st); System.exit(0); } } Neste exemplo, o programa abrirá uma caixa de diálogo perguntando o nome do usuário. Se o usuário apertar Cancel ou x, a variável st terá a referência null e, no primeiro if, o programa irá abortar. Caso o usuário pressione Ok sem ter digitado nada, o segundo if se torna falso, e a execução retorna para a primeira instrução após o while. Caso o usuário digite um nome qualquer, o segundo if se torna verdadeiro, executando a instrução break, que quebra o laço, executando a instrução imediatamente posterior. Assim, abre-se uma outra caixa de diálogo, contendo a mensagem “Seu nome é: <nome digitado>”. Modificando o programa para utilizar o comando continue, temos: import javax.swing.JOptionPane; public class ExemploContinue { public static void main(String[] args) { String st; while (true) { st = JOptionPane.showInputDialog(null,"Digite seu nome: "); if (st == null) continue; if (!st.equals("")) break; } JOptionPane.showMessageDialog(null,"Seu nome é: " + st); System.exit(0); } } Neste caso, se o usuário pressionar Cancel ou x, o primeiro if será verdadeiro, e executará o comando continue. Este comando retorna a execução para o início do laço, abrindo uma nova caixa de diálogo de entrada. Outros exemplos interessantes usando break e continue são vistos a seguir. public class ExemploContinue { public static void main(String[] args) { for (int i=0 ; i < 5 ; i++) { if (i == 3) continue; System.out.println("i = " + i); } } } Terá como saída: 39 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento i = 0 i = 1 i = 2 i = 4 E o programa: public class ExemploBreak { public static void main(String[] args) { for (int i=0 ; i < 5 ; i++) { if (i == 3) break; System.out.println("i = " + i); } } } Terá como saída: i = 0 i = 1 i = 2 Arrays Arrays são estruturas de dados que podem armazenar mais que um valor de um mesmo tipo de dado. Enquanto uma variável somente consegue armazenar um único valor, um array armazena um conjunto de valores. Em Java, os arrays são objetos. Isso significa que eles não se comportam como os demais tipos primitivos, e sim como instâncias de classes. Por isso, eles precisam ser declarados, instanciados (criados) e inicializados (ao contrário dos tipos primitivos, que precisam apenas ser declarados e inicializados). Os arrays podem ser unidimensionais, sendo chamados de vetores (não confundir com a classe Vector, que serve para outra função) ou multidimensionais, sendo chamados de matrizes. Vetores Uma maneira simples de pensar em um vetor é imaginá-lo como uma linha de uma tabela composta por diversas células, em que cada célula pode armazenar um valor. Veja o exemplo na tabela abaixo, do vetor vt. 40 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento vt[0] vt[1] vt[2] vt[3] 15 32 47 0 Note que a primeira posição do vetor é referenciada pelo número0 (zero), entre colchetes depois do nome da variável, vt. O número entre colchetes é o índice do vetor. Na prática, é necessário saber como realizar quatro operações básicas com vetores: declará-los, instanciá-los, inicializá-los e consultá-los. Declarando vetores A declaração de vetores é similar à declaração de variáveis, e pode ser feita de duas formas distintas: <tipo>[] <nome>; <tipo> <nome>[]; A única diferença entre essas formas é a posição dos colchetes. Em ambos os casos, a declaração do vetor inicia com o tipo de dado que ele irá armazenar, e termina com um ponto-e-vírgula. Veja dois exemplos: int[] vetorDeInteiros; char vetorDeCaracteres[]; Instanciando vetores Após declarar um vetor, é necessário instanciá-lo. A instanciação é o processo pelo qual você aloca um endereço de memória para um objeto. A instanciação pode ser entendida como a criação do vetor – instanciar um vetor significa lhe atribuir um endereço de memória no qual ele pode armazenar seus valores: a tentativa de armazenar um valor em um vetor antes de instanciá-lo acarretará em um erro. A sintaxe para a instanciação é a seguinte: <nome> = new <tipo>[<tamanho>]; O tipo da instanciação deve ser o mesmo utilizado em sua declaração. O exemplo a seguir instancia os dois vetores declarados anteriormente. vetorDeInteiros = new int[4]; vetorDeCaracteres = new char[3]; 41 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento Note que a declaração e a instanciação poderia ter sido feita em uma só linha: int[] vetorDeInteiros = new int[4]; char vetorDeCaracteres[] = new char[3]; Nota: No livro texto há um erro nessa parte, indicando que não é preciso utilizar os colchetes na declaração quando esta é feita junto à instanciação. Inicialização de vetores Para atribuir um valor a um vetor, basta indicar sua posição de memória e utilizar o operador de atribuição. vetorDeInteiros[0] = 5; vetorDeInteiros[1] = 7; vetorDeInteiros[2] = 9; vetorDeInteiros[3] = 11; Outra forma de se declarar, instanciar e inicializar um vetor é: int[] vetorDeInteiros = {5,7,9,11}; Consulta a vetores A consulta aos valores armazenados em um vetor também é bastante intuitiva: posicao2 = vetorDeInteiros[2]; posicao0 = vetorDeInteiros[0]; Cuidado com o tamanho do vetor Se você tentar acessar uma posição que não existe, como no exemplo abaixo: int[] vt = new int[5]; it[7] = 32; Acarretará em uma falha no programa: seu programa será abortado, lançando uma ArrayIndexOutOfBoundsException. Lembre-se que a posição 5 de um vetor de 5 posições não existe – as posições existentes vão de 0 a 4 (0, 1, 2, 3 e 4). Exemplo utilizando vetores 42 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento O exemplo abaixo ilustra o uso de vetores para construir a famosa seqüência de Fibonacci, na qual o número atual é a soma dos dois números anteriores a ela. public class ExemploDeVetores { public static void main(String[] args) { int[] it = new int[10]; it[0] = 1; it[1] = 1; for (int n = 2; n < it.length ; n++) { it[n] = it[n-1] + it[n-2]; } for (int n = 0; n < it.length ; n++) { System.out.print(it[n] + " "); } } } A saída do programa será: 1 1 2 3 5 8 13 21 34 55 Além do uso de vetores, este programa utiliza duas novas funções: a variável n é declarada duas vezes, uma em cada loop de for, e o programa usa a função System.out.print() ao invés da famosa System.out.println(). A declaração dupla da variável n é possível porque, como ela foi declarada dentro do loop de for, ela só existe ali, ou seja, só tem escopo dentro do loop. No segundo caso, foi usada a função print() porque a função println() automaticamente pula uma linha ao final da execução – o restante das funcionalidades é idêntica. Outra mudança ocorrida neste programa foi o uso do atributo length do vetor, utilizado como it.length. Como o array é um objeto, ele possui atributos, e um desses atributos é o atributo length, que retorna o comprimento do array. No caso, o comprimento é 10, conforme consta na instanciação. Matrizes O uso de matrizes é bem similar ao uso de vetores. A declaração de matrizes deve ser feita como: <tipo>[][] <nome>; <tipo> <nome>[][]; Ou ainda: <tipo>[] <nome>[]; 43 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento É importante entender um conceito no que diz respeito à matrizes: em Java, uma matriz nada mais é que um array de arrays. Veremos um exemplo simples do uso de uma matriz bidimensional quadrada para, em seguida, ver tipos mais complexos de matrizes. public class ExemploDeMatrizes { public static void main(String[] args) { int[][] it = {{1,2,3},{4,5,6},{7,8,9}}; for (int i = 0; i < it.length; i++) { for (int j = 0; j < it[i].length; j++) { System.out.print(it[i][j] + " "); } System.out.println(""); } } } A saída do exemplo será: 1 2 3 4 5 6 7 8 9 No exemplo, foi utilizada a inicialização rápida de matrizes – a declaração, instanciação e inicialização foram feitas na mesma linha. Em seguida, o primeiro loop de for conta o tamanho da primeira dimensão da matriz, retornada pela expressão it.length. O segundo loop de for não conta o tamanho da segunda dimensão da matriz – ele conta o tamanho da primeira dimensão (e única, neste caso) de cada array referenciado por it[n], ou seja, de cada array “pendurado” no vetor principal. Isso ocorre porque, em Java, ao contrário da matemática, uma matriz não precisa ser retangular – ela pode ter qualquer formato. O exemplo abaixo ilustra o uso de uma matriz não retangular. public class ExemploDeMatrizes { public static void main(String[] args) { int[][] it = new int[3][]; it[0] = new int[3]; it[1] = new int[2]; it[2] = new int[3]; it[0][0] = 1; it[0][1] = 2; it[0][2] = 3; it[1][0] = 4; it[1][1] = 5; it[2][0] = 6; it[2][1] = 7; it[2][2] = 8; for (int i = 0; i < it.length; i++) { for (int j = 0; j < it[i].length; j++) { System.out.print(it[i][j] + " "); } System.out.println(""); } } } 44 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento A saída deste programa será: 1 2 3 4 5 6 7 8 Neste caso, o valor retornado por it.length é 3 – este é o tamanho da dimensão principal da matriz. Na primeira posição, it[0], “penduramos” outro array de 3 posições, na segunda, it[1], “penduramos” um array de apenas 2 posições e, na terceira, “penduramos” um array de 3 posições. Isto é possível porque, na declaração de it, dissemos it seria um array de arrays com “espaço para 3 arrays” (denotado na expressão new int [3][]). No segundo loop de for, quando perguntado do tamanho do array contido na posição it[1], o programa responde 2, ao invés de 3, como nos outros casos. O argumento da função main Você deve ter percebido agora o significado dos colchetes no argumento da função main() que inicia o programa. O argumento da função main() é um array de Strings unidimensional. O tamanho e a composição deste array depende da forma como o programa foi chamado. Veja o exemplo abaixo: public class ExemploMain { public static void main(String[] args) { for (int n = 0; n < args.length ; n++) { System.out.println("args[" + n + "] = " + args[n]); } } } Este exemplo irá ecoar na tela todas as strings recebidas comoargumento pelo método main(). Este argumento é composto das palavras que foram digitas após a chamada da execução do programa, como no exemplo: java ExemploMain Ola Mundo Irá resultar em: args[0] = Ola args[1] = Mundo Note que você poderia colocar uma string numérica para fazer o parsing para um inteiro. Veja o exemplo: 45 Apostila de Java 1ª Parte Faculdade Fortium – Campus GAMA/DF LINGUAGEM DE PROGRAMAÇÃO Prof.: Paulo Guilherme Nascimento public class ExemploMain { public static void main(String[] args) { if (args.length == 2) { int a = Integer.parseInt(args[0]); int b = Integer.parseInt(args[1]); System.out.println("a + b = " + (a+b)); } else { System.out.println("Erro: Você deve passar dois argumentos a este programa."); } } } E, se chamada dessa forma: java ExemploMain 5 7 Irá resultar em: a + b = 12 Você é responsável pelo uso deste argumento – certifique-se de que foi realmente passado um argumento para a função antes de utilizá-lo no programa, para não correr o risco de ter uma ArrayIndexOutOfBoundsException. Importante: No exemplo, no comando System.out.println(“a + b = “ + (a+b)); a operação matemática a+b aparece entre parênteses. Isto não é por acaso – ela foi colocada entre parênteses para ter precedência sobre o outro operador +, que é usado para concatenação. Se os parênteses fossem omitidos, a saída seria: a + b = 57 Que é a concatenação da string “a + b =” com os inteiros 5 e 7. Nota: para utilizar comandos através da chamada do programa no Netbeans, procure a guia FILE e então <nomedoprojeto> PROPERTIES, depois na opção RUN e preencha o campo ARGUMENTS. Referências [1] SANTOS, Rui Rossi dos. Programando em Java 2 Teoria & Aplicações. Axcel Books, 2004. [2] MECENAS, Ivan. Java2 Fundamentos, Swing e JDBC, Alta Books, 2005 [3] DEITEL, H.M. DEITEL, P.J. Java TM Como Programar, Pearson Prentice Hall, 2005. [4] SIERRA, Kathy. BATES, Bert. Certificação Sun para Programadaor Java TM , 2006, Alta Books. [5] Linguagem de Programação Java: http://pt.wikipedia.org/wiki/Java_ %28linguagem_de_programa%C3%A7%C3%A3o%29 [6] Página oficial da Sun: www.java.sun.com 46 Apostila de Java 1ª Parte
Compartilhar