Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas

Curso de Java, Notas de estudo de Engenharia Informática

Criando seus primeiros programas em Java, ensina desde criar até compilar seu primeiro código.

Tipologia: Notas de estudo

2011

Compartilhado em 10/06/2011

fabio-higor-8
fabio-higor-8 🇧🇷

2 documentos

1 / 64

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Introdução
Tendo sido originalmente concebida para o desenvolvimento de pequenos aplicativos e
programas de controle de aparelhos eletrodomésticos e eletroeletrônicos, Java mostrou-
se ideal para ser usada na rede Internet. O que a torna tão atraente é o fato de programas
escritos em Java poderem ser executados virtualmente em qualquer plataforma, mas
principalmente em Windows, Unix e Mac. Em meio a essa pluralidade, Java é um
idioma comum, falado por todos. Isto significa que Java é ideal para expressar idéias em
forma de programas universalmente aceitos. Soma-se a isso o fato de programas Java
poderem ser embutidos em documentos HTML, podendo assim ser divulgados pela
rede. Diferente da linguagem C, não é apenas o código fonte que pode ser
compartilhado pela rede, mas o próprio código executável compilado, chamado
bytecodes.
Em contraste com a letargia de documentos tradicionais, Java acrescenta a
interatividade entre o usuário e o documento que está sendo consultado, tornando-o
mais expressivo, agradável e surpreendente. Java é ideal para a elaboração de material
educacional, pois permite ilustrar claramente os conceitos enquanto possibilita um
ensino individualizado.
Um exemplo excelente para ilustrar a utilidade da Java no ensino de matemática é o
livro eletrônico de geometria euclideana, Elementos de Euclides na qual, a ilustração da
demonstração é iterativa graças à Aplet Java.
Java foi desenvolvida por um grupo de pesquisadores da SUN Microsystems por volta
de 1990, pouco antes da explosão da Internet. Essa linguagem possui estrutura muito
semelhante à da linguagem C, da qual descende imediatamente. Java tem em comum
com a linguagem C++ o fato de ser orientada a objetos e mantém com esta uma alto
grau de semelhança. Esse paradigma de programação consiste de um grau a mais na
abstração da programação, em comparação com a programação estruturada, e tem se
mostrado extremamente útil na produção de programas cada vez mais sofisticados, em
menor tempo e com maior qualidade. A programação orientada a objetos (OOP) é hoje
universalmente adotada como padrão de mercado, e muitas linguagens tradicionais
foram aperfeiçoadas para implementar esse paradigma, como C++, Object Pascal, etc.
Há uma certa curiosidade por detrás do nome dado a essa linguagem de programação.
Java é o nome de uma ilha do Pacífico, onde se produz uma certa variedade de café
homônimo. A inspiração bateu à equipe de desenvolvimento ao saborear esse café em
uma lanchonete local. Deram-se conta de como era extremamente apreciado por
profissionais da área de software (ao menos nos Estados Unidos), de modo que não foi
menos justo fazer-lhe homenagem ao batizar uma nova linguagem de programação.
Atualmente, o site JavaSoft mantém informações atualizadas sobre o desenvolvimento
da linguagem Java e suas relações com o mercado, assim como utilitários e ferramentas
disponíveis para serem baixados gratuitamente.
Como Java é executado
Um programa fonte escrito em linguagem Java é traduzido pelo compilador para os
bytecodes, isto é, o código de máquina de um processador virtual, chamado Java Virtual
Machine (JVM). A JVM é um programa capaz de interpretar os bytecodes produzidos
pelo compilador, executando o programa cerca de 20 vezes mais lento do que C. Pode
parecer ruim, mas é perfeitamente adequado para a maioria das aplicações. Com isto,
um programa Java pode ser executado em qualquer plataforma, desde que esteja dotada
de uma JVM. É o caso dos programas navegadores mais populares, como o Netscape
Navigator e o Internet Explorer, que já vêm com uma JVM. A vantagem desta técnica é
evidente: garantir uma maior portabilidade para os programas Java em código-fonte e
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f
pf40

Pré-visualização parcial do texto

Baixe Curso de Java e outras Notas de estudo em PDF para Engenharia Informática, somente na Docsity!

Introdução

Tendo sido originalmente concebida para o desenvolvimento de pequenos aplicativos e programas de controle de aparelhos eletrodomésticos e eletroeletrônicos, Java mostrou- se ideal para ser usada na rede Internet. O que a torna tão atraente é o fato de programas escritos em Java poderem ser executados virtualmente em qualquer plataforma, mas principalmente em Windows, Unix e Mac. Em meio a essa pluralidade, Java é um idioma comum, falado por todos. Isto significa que Java é ideal para expressar idéias em forma de programas universalmente aceitos. Soma-se a isso o fato de programas Java poderem ser embutidos em documentos HTML, podendo assim ser divulgados pela rede. Diferente da linguagem C, não é apenas o código fonte que pode ser compartilhado pela rede, mas o próprio código executável compilado, chamado bytecodes.

Em contraste com a letargia de documentos tradicionais, Java acrescenta a interatividade entre o usuário e o documento que está sendo consultado, tornando-o mais expressivo, agradável e surpreendente. Java é ideal para a elaboração de material educacional, pois permite ilustrar claramente os conceitos enquanto possibilita um ensino individualizado.

Um exemplo excelente para ilustrar a utilidade da Java no ensino de matemática é o livro eletrônico de geometria euclideana, Elementos de Euclides na qual, a ilustração da demonstração é iterativa graças à Aplet Java.

Java foi desenvolvida por um grupo de pesquisadores da SUN Microsystems por volta de 1990, pouco antes da explosão da Internet. Essa linguagem possui estrutura muito semelhante à da linguagem C, da qual descende imediatamente. Java tem em comum com a linguagem C++ o fato de ser orientada a objetos e mantém com esta uma alto grau de semelhança. Esse paradigma de programação consiste de um grau a mais na abstração da programação, em comparação com a programação estruturada, e tem se mostrado extremamente útil na produção de programas cada vez mais sofisticados, em menor tempo e com maior qualidade. A programação orientada a objetos (OOP) é hoje universalmente adotada como padrão de mercado, e muitas linguagens tradicionais foram aperfeiçoadas para implementar esse paradigma, como C++, Object Pascal, etc.

Há uma certa curiosidade por detrás do nome dado a essa linguagem de programação. Java é o nome de uma ilha do Pacífico, onde se produz uma certa variedade de café homônimo. A inspiração bateu à equipe de desenvolvimento ao saborear esse café em uma lanchonete local. Deram-se conta de como era extremamente apreciado por profissionais da área de software (ao menos nos Estados Unidos), de modo que não foi menos justo fazer-lhe homenagem ao batizar uma nova linguagem de programação. Atualmente, o site JavaSoft mantém informações atualizadas sobre o desenvolvimento da linguagem Java e suas relações com o mercado, assim como utilitários e ferramentas disponíveis para serem baixados gratuitamente.

Como Java é executado

Um programa fonte escrito em linguagem Java é traduzido pelo compilador para os bytecodes , isto é, o código de máquina de um processador virtual, chamado Java Virtual Machine (JVM). A JVM é um programa capaz de interpretar os bytecodes produzidos pelo compilador, executando o programa cerca de 20 vezes mais lento do que C. Pode parecer ruim, mas é perfeitamente adequado para a maioria das aplicações. Com isto, um programa Java pode ser executado em qualquer plataforma, desde que esteja dotada de uma JVM. É o caso dos programas navegadores mais populares, como o Netscape Navigator e o Internet Explorer, que já vêm com uma JVM. A vantagem desta técnica é evidente: garantir uma maior portabilidade para os programas Java em código-fonte e

compilados. Porém, as JVM tendem a ser programas extensos que consomem muitos recursos, restringindo assim o tamanho das aplicações escritas em Java.

Atualmente, já existem compiladores capazes de traduzir bytecodes para instruções de máquina nativas, como o Just In Time compiler (ou JIT), tornando os programas ainda mais rápidos. Este compilador requer uma versão específica para cada plataforma onde se pretende que o programa Java seja executado. Em contrapartida à maior velocidade de execução está também uma maior necessidade de memória, pois os bytecodes compilados, em geral, ficam três vezes maiores do que o original. Uma alternativa bem mais interessante, e talvez muito mais viável, é a implementação da JVM em hardware na forma de uma placa ou microchip. A primeira iniciativa neste sentido é da Sun Microelectronics, que está produzindo os chips picoJava I TM^ , microJavaTM^ e UltraJava TM (^). Estes são capazes executar diretamente bytecodes, acelerando em milhares de vezes

a velocidade de execução. Isto permitirá o desenvolvimento viável de aplicativos cada vez mais complexos, abrangentes e funcionais. Espera-se que estas soluções sejam brevemente empregadas na fabricação de telefones celulares, pagers, jogos, organizadores pessoais digitais, impressoras e eletrodomésticos de consumo, além aplicações mais sérias como estações de trabalho dotadas do sistema operacional JavaOSTM^. Trata-se certamente do futuro das soluções para aplicações de rede.

[índice, seguinte]

Já se tornou clássica a idéia de que para aprender uma nova linguagem de programação não se deve ir direto à descrição sua formal. Ao invés disso, é melhor examinar cuidadosamente um pequeno programa escrito nessa linguagem, o mais simples possível, mas que permita "quebrar o gelo". Isso faz sentido pois, por exemplo, quando vamos aprender Inglês, ou outro idioma qualquer, não iniciamos com a leitura compenetrada de um livro de gramática, mas aprendemos algumas estruturas simples e procuramos exercitá-las, adiando o estudo rigoroso para quando estivermos suficientemente maduros. Ao compreender as diversas partes componentes do exemplo, já teremos dado um grande passo para podermos escrever qualquer programa.

Seguindo essa linha, apresentamos nosso primeiro programa, o clássico "Alô pessoal!". O objetivo deste programa é simplesmente escrever na tela a frase "Alô pessoal!". Vejamos como é o código fonte:

public class AloPessoal { public static void main(String args[]) { System.out.println("Alo pessoal!"); } }

Digitando o programa

apenas aceitar que todo programa Java deve conter ao menos uma classe, e que é dentro de uma classe que vão os dados e os procedimentos. Notemos ainda que todo programa Java (mas não as applets) deve ter uma classe dotada de um procedimento chamado main. Os procedimentos em Java são chamados métodos. Os métodos encerram um conjunto de declarações de dados e de comandos que são executados mediante a chamada do método por seu nome. Vamos estudar os métodos em detalhe mais adiante. O método main é o ponto onde se dá o início da execução do programa, isto é, um método chamado automaticamente pela JVM.

Voltando ao nosso programinha AloPessoal , o código a ser executado é

System.out.println("Alo pessoal!"); System.out.println é o nome de uma função que serve para escrever informações textuais na tela. Os dados a serem escritos, devem estar delimitados entre os parênteses "(" e ")". "Alo pessoal!" é uma frase. Em computação, uma palavra ou uma frase que tenha função literal é denominada string. Em Java, a representação de uma string constante se dá colocando os caracteres entre aspas, por exemplo: "Imagem", "Rio de Janeiro", "Brasília", etc, são strings constantes. Note que existe um ; (ponto e vírgula) no final da linha, logo após o ")". Em Java, é obrigatório colocar um ponto e vírgula após cada comando. Isso porque um comando pode ser quebrado em múltiplas linhas, sendo necessário sinalizar de algum modo onde é que o comando termina. Java é sensível ao tipo de caixa, isto é, distingue caixa alta (maiúsculo) da caixa baixa (minúsculo). Os programadores acostumados a linguagem C e C++ vão certamente sentir-se em casa; porém os programadores acostumados à linguagem PASCAL devem ficar mais atentos.

Mais exemplos

Podemos escrever "Alo pessoal!" escrevendo primeiro, "Alo " e depois, "pessoal!". Para isso, o programa deve ser alterado da seguinte forma: public class Alo { public static void main(String args[]) { System.out.print("Alo "); System.out.println("pessoal!"); } } Para escrever dados genéricos na tela, existe o comando System.out.print que escreve o dado e mantém o carro na mesma linha. Há também o System.out.println que escreve dados e muda o carro para a próxima linha. Podemos concatenar dois ou mais strings usando o operador "+". Por exemplo, "Alo " + "pessoal!" é o mesmo que "Alo pessoal!". Para escrever um número, basta escrever [string]+n onde [string] é um string qualquer e n é um número. Por exemplo:

public class Numero { public static void main(String args[]) { System.out.println("O valor é " + 29); } } Como o lado esquerdo da expressão é um string, 29 é convertido para string "29" e é concatenado com "O valor é ". Compilando e executando esse exemplo como fizemos anteriormente, devemos obter na tela:

O valor é 29 Observemos que os comandos System.out.print e System.out.println escrevem uma informação de cada vez. Desta forma, precisamos usar "+" para unir "O valor e " com 29 para formar uma única string. No exemplo acima, nada impede que os dados sejam escritos em duas etapas: primeiro, "O valor e " e depois, 29. Neste caso, teríamos:

public class Numero { public static void main(String args[]) { System.out.print("O valor e "); System.out.println(29); } } Entretanto, a primeira abordagem parece mais razoável pois torna a programação mais clara e concisa, além de economizar comandos.

Usando variáveis

Uma variável é simplesmente um espaço vago, reservado e rotulado para armazenar dados. Toda variável tem um nome que a identifica univocamente e um valor, que corresponde à informação a ela atribuida. Por exemplo, int n; especifica que n é o nome de uma variável que pode armazenar um número inteiro como valor. Em geral, num contexto onde aparece o nome de uma variável ocorre a substituição por seu valor. O valor de uma variável pode mudar muitas vezes durante a execução de um programa, por meio de atribuições de valor. Há diversos tipos de variáveis em Java, correspondendo aos vários tipos de dados aceitos. A discussão sobre esses tipos de dados será feita no próximo capítulo. Antes porém, vamos fazer um pequeno programa que declara uma variável interira, atribui a ela uma constante, e imprime seu valor na tela. public class Numero { public static void main(String args[]) { int n; n = 17+21; System.out.println("O valor numérico é " + n); } } O local onde uma variável está declarada é extremamente importante. Uma variável é conhecida apenas dentro de algum escopo. Por exemplo, uma variável declarada no escopo de uma classe (fora de um método) é conhecida por qualquer método que esteja declarado dentro dessa mesma classe, enquanto uma variável declarada no escopo de um procedimento é conhecida apenas por esse procedimento. Há ainda outros tipos de escopo, como veremos mais adiante. O sinal "=" é um operador, utilizado para atribuir um valor a uma variável. Por exemplo, n = 1; faz com que o valor 1 seja armazenado na variável n. Há também os operadores usuais de adição, subtração, multiplicação e divisão de números. Estes são representados pelos símbolos " + ", " - ", " ***** " e " / ", respectivamente.

Ao executar o programa acima (claro, depois de compilá-lo), ele escreve

O valor numerico é 38

Introduzindo comentários no código

Um comentário é uma porção de texto que não tem função para o compilador Java, mas é útil ao leitor humano. Assim sendo, um comentário é identificado mas ignorado completamente pelo compilador Java. A utilidade dos comentários é óbvia: deve conter

Eis uma visão geral dos tipos que serão abordados neste capítulo:

Tipo Descrição boolean (^) Pode assumir o valor true ou o valor false

char (^) Caractere em notação Unicode de 16 bits. Serve para a armazenagem de dados

alfanuméricos. Também pode ser usado como um dado inteiro com valores na faixa entre 0 e 65535. byte (^) Inteiro de 8 bits em notação de complemento de dois. Pode assumir valores

entre -2^7 =-128 e 2^7 -1=127. short (^) Inteiro de 16 bits em notação de complemento de dois. Os valores possívels

cobrem a faixa de -2 -15=-32.768 a 2^15 -1=32. int (^) Inteiro de 32 bits em notação de complemento de dois. Pode assumir valores

entre -2^31 =2.147.483.648 e 2^31 -1=2.147.483.647. long (^) Inteiro de 64 bits em notação de complemento de dois. Pode assumir valores

entre -2^63 e 2^63 -1. float (^) Representa números em notação de ponto flutuante normalizada em precisão

simples de 32 bits em conformidade com a norma IEEE 754-1985. O menor valor positivo represntável por esse tipo é 1.40239846e-46 e o maior é 3.40282347e+ double (^) Representa números em notação de ponto flutuante normalizada em precisão

dupla de 64 bits em conformidade com a norma IEEE 754-1985. O menor valor positivo representável é 4.94065645841246544e-324 e o maior é 1.7976931348623157e+

Ao contrário do que acontece com outras linguagens de programação, as características dos tipos de dados listados acima idependem da plataforma em que o programa deverá ser executado. Dessa forma, os tipos de dados primitivos são realmente únicos e garantem a capacidade de intercâmbio de informações entre diversos tipos de computadores, aliviando o programador da preocupação e da árdua tarefa de converter dados em formatos apropriados para a portagem.

Tipo Boolean

Este é o tipo de dado mais simples encontrado em Java. Uma variável booleana pode assumir apenas um entre dois valores: true ou false. Algumas operações possíveis em Java como a<=b , x>y , etc têm como resultado um valor booleano, que pode ser armazenado para uso futuro em variáveis booleanas. Estas operações são chamadas operações lógicas. As variáveis booleanas são tipicamente empregadas para sinalizar alguma condição ou a ocorrência de algum evento em um programa Java. Por exemplo: boolean fim_do_arquivo = false; é a declaração de uma variável do tipo boolean , cujo nome é fim_do_arquivo. O valor false à direita do sinal "=" indica que a variável recebe esse valor como valor inicial. Sem essa especificação o valor de uma variável é impredicável, podendo ser qualquer um dos valores possíveis para seu tipo (neste caso true ou false ). Aproveitando o ensejo, há nessa linha a essência da declaração de qualquer variável em Java:

  1. Informar o tipo de dado que deseja declarar ( boolean )
  2. Informar o nome que será usado para batizar a variável ( fim_do_arquivo )
  3. (^) Atribuir à variável um valor inicial ( = false )
  4. Terminar a declaração com um ponto-e-vírgula ";".

Uma palavra sobre identificadores

Na declaração acima usamos o nome fim_do_arquivo para designar a variável. Um nome de variável, assim como nome de um método, classe, rótulo e dezenas de outros itens lexicográficos, constitui o que é chamado um identificador. Uma vez criado, um identificador representa sempre o mesmo objeto a ele associado, em qualquer contexto em que seja empregado. As seguintes regras regem a criação de identificadores:

  • O primeiro caracter de um identificador deve ser uma letra. Os demais caracteres podem ser quaisquer seqüências de numerais e letras
  • Não apenas os numerais e letras latinas podem ser empregadas, como também letras de quaisquer outro alfabeto
  • Devido a razões históricas, o underscore "_" e o sinal de dolar "$" são considerados letras e podem ser usados nos identificadores
  • Assim como em outras linguagens, como C e C++, os identificadores distinguem o tipo de caixa das letras, isto é, as maiúsculas são consideradas distintas das minúsculas. Isso significa que fim_de_arquivo é um identificador diferente de Fim_De_Arquivo
  • Os identificadores não podem ser palavras chave, como: class , for , while , public , etc

Tipos de dados inteiros

Os tipos de dados primitivos byte , int , char , short e long constituem tipos de dados inteiros. Isso porque variáveis desses tipos podem conter um valor numérico inteiro dentro da faixa estabelecida para cada tipo indiivdual. Por exemplo, um byte pode conter um inteiro entre -128 e 127, enquanto um short pode conter um valor entre -32.768 e 32.767. Já o tipo long é suficiente para contar todos os mosquitos do Pantanal Matogrossense.

Há diversas razões para se utilizar um ou outro dos tipos inteiros em uma aplicação. Em geral, não é sensato declarar todas as variáveis inteiras do programa como long. Raramente os programas necessitam trabalhar com dados inteiros que permitam fazer uso da máxima capacidade de armazenagem de um long. Além disso, variáveis grandes consomem mais memória do que variáveis menores, como short.

Obs: Se alguma operação aritmética cria um resultado que excede um dos limites estabelecidos para o tipo inteiro empregado, não há qualquer indicação de erro para avisar sobre essa ocorrência. Ao invés disso, um complemento de dois do valor obtido será o resultado. Por exemplo, se a variável for do tipo byte , ocorrem os seguintes resultados: 127+1 = -128 , 127+9=-120 e 127+127=-2. Entretanto, uma excessão do tipo ArithmeticException é levantada caso ocorra uma divisão por zero. As excessões e seus mecanismos serão abordados no Capítulo 8. Vejamos o seguinte código: public class Arith { public static void main(String args[]) { byte a = 127; short b = 32767; int c = 2147483647; long d = 9223372036854775807L; int e = 0; a += 1; b += 1;

soma passa a ser o novo valor. Esse padrão também é obedecido para as operações -=, *=, /= e %=. Temos assim as seguintes correspondências:

*x += 5 x=x+ x -= y x = x - y x = 2 x = x * 2 z /= 4 z = z / 4

etc. Os operadores de incremento e decremento referem-se a apenas uma variável (logo são chamados de unários). Por exemplo, o operador de incremento soma um ao operando conforme o exemplo: x++; é uma maneira muito mais concisa de se escrever x = x + 1. Mas não só, esses operadores se comportam de modo diferente quando seguem ou precedem o nome de uma variável. Se o operador precede o nome da variável, então o incremento (ou decremento) ocorre antes que o valor da variável seja tomado para a expressão aritmética. No seguinte exemplo, o valor das variáveis x e y será 6: int x = 5; int y = ++x; Porém, no próximo exemplo o valor de x será 6 enquando que o valor de y será 5: int x = 5; int y = x++; Vejamos alguns exemplos de declarações e de utilizações de operações envolvendo tipos inteiros: byte j = 60; short k = 24; int l = 30; long m = 12L; long resuldato = 0L;

resultado += j; // resultado = 60 (0 mais 60) resultado += k; // resultado = 84 (60 mais 24) resultado /= m; // resultado = 7 (84 dividido por 12) resultado -= l; // resultado = -23(7 menos 30) resultado = -resultado; // resultado = 23 ( -(-23) ) resultado = %= m; // resultado = 11 (resto de 23 div. 12)

Tipo caracter

Uma variável do tipo char armazena um caractere Unicode. Um caractere Unicode é um caractere de 16 bits, sendo que de 0 a 225 correspondem aos caracteres do código ASCII (a tabela ASCII é uma tabela padronizada internacionalmente de associações entre caractere e a sua representação numérica no computador). Uma constante do tipo caractere é representada colocando-se entre apóstrofos, ou pelo valor numérico correspondente na tabela Unicode (ou ASCII), ou ainda, pela sequência '\x' onde x especifica o caractere a ser referido. Esta especificação de sequência de escape obedece às mesmas convenções do C/C++. Por exemplo: 'a', 'f', '\n', etc, são constantes do tipo char.

Tipos de ponto flutuante

Em Java, existem duas categorias de de variáveis de ponto flutuante: float armazena valores numéricos em ponto flutuante de precisão simples e double de precisão dupla. Ambas seguem norma: IEEE Standard for Binary Floating Point Arithmetic , ANSI/

IEEE Std. 754-1985 (IEEE, New York). O fato de obedecer a essa norma é que torna os tipos de dados aceitos pela linguagem Java tão portáveis. Esses dados serão aceitos por qualquer plataforma, independendo do tipo desistema operacional e do fabricante do computador. A representação dos valores em ponto flutuante pode ser feita usando a notação decimal (exemplo: -24.321) ou a notação científica (exemplo: 2.52E-31). Além dos possíveis valores numéricos que uma variável de ponto flutuante pode assumir há também os seguintes:

  • menos infinito
  • mais infinito
  • zero
  • NAN - not a number Estes são requeridos pela norma. O mais infinito é usado, por exemplo, ao somarmos 1 ao maior valor possivelmente representável por esse sistema. Muitas das operações realizáveis com inteiros (porém não todas) têm análogas para números de ponto flutuante. Eis um resumo:

Operação Descrição

=, +=, -=, *=, /= Operadores de atribuição

==, != Operadores de igualdade e diferença

<, <=, >, >= Operadores de desigualdade

+, - Sinais unários

+, -, *, / Adição, subtração, multiplicação e divisão

+=, -=, *=, /= Operadores de atribuição com adição, subtração, multiplicação e divisão

++, -- Operadores unários de incremento e decremento

[anterior, índice, seguinte] Semelhante às liguagens C, C++ e Pascal, a linguagem Java também dá suporte a vetores e matrizes ( arrays ) de diversas formas. Os vetores constituem uma forma muito conveniente de organizar informações em fileira. Por exemplo, podemos formar um vetor com as notas de cinco alunos de uma sala de aula do seguinte modo: float nota[] = { 7.8, 8.4, 4.2, 1.8, 6.4 }; Neste caso nota[0] é a nota do primeiro aluno, isto é, 7.8, nota[1] é a nota do segundo, ou seja, 8.4, e assim por diante. A utilização de vetores e matrizes em Java envolve três etapas:

  1. Declarar o vetor ou matriz. Para isto, basta acrescentar um par de colchetes antes ou depois do nome da variável. Por exemplo: int ind[]; double A[][],T[][][]; int []nota;

funções, procedimentos ou subrotinas. Estes são apenas conjuntos ordenados de declarações de dados, comandos e expressões. Em termos simples, são os métodos que realizam todas as tarefas para as quais o programa foi escrito, por exemplo, realizar cálculos, resumir informações de um arquivo, produzir um relatório, criar um gráfico, gerar um filme de animação, etc.

Classes

Os métodos, assim como os dados, têm um local de residência, as classes. Mais adiante, vamos estudar as classes em detalhes. Por hora, precisamos apenas de alguns poucos conceitos para poder entender os métodos. Pensemos uma classe como sendo um conjunto de dados (variáveis) e métodos (funções) da forma: class [nome] { [dados e métodos] } onde [nome] é um identificador que define o nome da classe, e o par de chaves delimita uma região para declaração de variáveis e métodos. A declaração de variáveis já foi vista anteriormente no capítulo sobre tipos de dados. Uma classe pode ser privativa ou pública. Uma classe privativa é declarada como no exemplo acima e é conhecida apenas no escopo delimitado pelo arquivo que a contém. Como um programa Java pode ser quebrado em múltiplos arquivos de código fonte distintos, pode ser necessário que as diversas partes integrantes do programa interajam, trocando dados entre si e chamando métodos umas das outras. Isso torna-se possível através das classes públicas, as quais são conhecidas por qualquer arquivo fonte que componha o programa. Para tornar uma classe pública, basta preceder sua declaração pela palavra-chave public como no seguinte exemplo: public class [nome da classe] { [dados e métodos] } Há uma convenção em Java que estabelece que deve haver exatamente uma classe pública para cada arquivo-fonte de que consiste um programa Java, e seu nome deve ser precisamente o nome do arquivo, sem o sufixo .java. Desse modo, existe uma correspondência biunívoca entre as classes públicas e os arquivos-fonte que as contém.

Podemos declarar uma classe a partir do chão, com todos os seus dados e métodos, ou podemos declarar uma classe derivando-a a partir de uma outra já existente. Este é um recurso muito útil, pois permite aproveitar um esforço de elaboração anterior, aumentando significativamente a produtividade da programação, e diminuindo o tamanho do código objeto. Suponhamos por exemplo, que tenhamos declarado previamente a seguinte classe:

class Polígono { int cx, cy; // Coordenadas do centro do polígono } Esta classe define em linhas gerais o que é um polígono, guardando uma única característica comum a qualquer polígono, isto é, as coordenadas de seu centro. Agora, suponhamos que desejamos criar uma classe para guardar informações sobre um quadrado. Neste caso, não precisamos criar uma classe que dê as coordenadas do centro do quadrado assim como as suas dimensões. Basta fazer simplesmente: class Quadrado extends Polígono { int lado; // Comprimento de um lado do quadrado } A classe quadrado declarada desse modo se diz uma classe derivada da classe Poligono, da qual herda os dados (e os métodos) nela contidos. Esta declaração é equivalente a

class Quadrado { int cx, cy; // Coordenadas do centro do polígono int lado; // Comprimento de um lado do quadrado } Desejando fazer uma classe para representar um retângulo, bastaria fazer então class Retângulo extends Polígono { int base, alt; // Base e altura do retângulo }

Objetos

Uma particular instância de uma classe é chamada objeto. Para entender a diferença entre classes e objetos, fazemos alusão à metáfora da fábrica de torradeiras. A fábrica de torradeiras não é uma torradeira, mas define o tipo de produto que sai dela, isto é, as torradeiras. Do mesmo modo a torradeira não é a fábrica, mas o produto feito por ela. Comparamos as classes às fabricas e os objetos aos produtos feitos por elas. Grosso modo, podemos dizer que as classes não ocupam espaço na memória, por serem abstrações, equanto que, os objetos ocupam espaço de memória por serem concretizações dessas abstrações. Nas declarações acima, introduzimos algumas classes que permitem representar polígonos. Porém, não instanciamos nenhuma das classes criando particulares objetos a partir dessas classes. Por exemplo, a partir da classe quadrado, podemos fazer objetos representando quadrados de diversos comprimentos laterais, ou retângulos de diferentes dimensões: Quadrado A, B, C; Retângulo D; A.lado = 1; // O quadrado A terá os lados de comprimento 1 B.lado = 2; // O quadrado B terá os lados de comprimento 2 C.lado = 7; // O quadrado C terá os lados de comprimento 7 D.base = 3; // O retangulo D terá base 3 e ... D.alt = 4; // altura 4, e centrado na origem D.cx = 0; D.cy = 0; As declarações acima são semelhantes às que vimos no capítulo anterior, com excessão de que no lugar do nome que identifica o tipo de dado estamos usando o nome de uma classe. Neste exemplo, as classes Quadrado e Retângulo foram empregadas para declarar os objetos (ou variáveis) A, B, C e D.

Em certo sentido as classes complementam os tipos de dados nativos da linguagem Java, com tipos de dados complexos criados pelo programador. Esse fato, aliado à possibilidade de derivar classes, tornam as linguagens orientadas a objetos extremamente producentes.

Chamando métodos

Um método entra em ação no momento em que é chamado. Isto pode ocorrer explicitamente ou implicitamente. A chamada explícita se dá por ordem do programador através da execução de um comando ou expressão contendo o nome do método. Em nosso programa AloPessoal fizemos uma chamada explícita do método System.out.println para mostrar um texto na tela do computador. As chamadas implícitas ocorrem quando o interpretador Java chama um método por sua própria deliberação. A chamada do método main é um exemplo de chamada impícita. O interpretador Java chama esse método para dar início à execução do programa.

Declarando métodos

Os moderadores de acesso são empregados para restringir o acesso a um método. Entretanto, independentemente do moderador escolhido, um método é sempre acessível, isto é, pode ser chamado, a partir de qualquer outro método contido na mesma classe. Os moderadores de acesso existentes em Java são os seguintes:

  • public : O método declarado com este moderador é público e pode ser chamado a partir de métodos contidos em qualquer outra classe. Esta é a condição de menor restrição possível.
  • protected : O método é protegido pode ser chamado por todas as classes que compõe um conjunto maior chamado package. Veremos adiante que as packages são um modo conveniente de organizar diversas classes que estão em estreito relacionamento.

Obs: é importante avisar que você pode ter problemas em identificar violações com respeito à chamada de métodos protegidos. Isso se deve ao fato do compilador não sinalizar esse fato precisamente, isto é, a tentativa de chamar um método protegido a partir de uma classe que não faz parte do package. Ao invés disso a mensagem poderá se parecer com a seguinte: No method matching funcao() found in class Matematica

  • friendly : Uso do método é permitido dentro da classe que o contém, assim como dentro de qualquer classe que tenha sido derivada dessa classe, ainda que esteja fora do package. Este é o moderador default, isto é, aquele que é assumido se nenhum moderador for explicitamente especificado.
  • private : O método é privativo da classe que o contém e seu uso é vedado a qualquer outra classe.
  • private protected : o método é acessível pela classe que o contém, assim como por qualquer classe que tenha sido derivada dessa classe. Porém, isso somente é permitido apenas dentro de um mesmo arquivo-fonte. Exemplo: // classe de numero class numero { double x=1; public void print1() { System.out.println("O valor e "+x); } void print2() { System.out.println("O valor e "+x); } } // classe principal public class PrintNum { public static void main(String args[]) { numero num = new numero(); num.print1(); // correto num.print2(); // ilegal } } O exemplo acima dará um erro, pois não pode acessar o print2. O método print1 é definido como public e portanto, está disponível a qualquer classe, mas o print2 não tem especificação (logo, é assumido como friendly ) e portanto, a classe principal PrintNum não pode acessa-lo.

Modificador do Método

O modificador do método permite especificar algumas propriedades de um método, determinando como classes derivadas podem ou não redefinir ou alterar o método, e de que forma esse método será visível.

  • static: o método é compartilhado por todos os objetos instanciados a partir da mesma classe. Um método static não pode acessar qualquer variável declarada dentro de uma classe (salvo se a variável estiver declarada também como static , o que veremos mais adiante), pois não é capaz de dicernir entre os diferentes objetos que compartilham esse método.
  • abstract : Podemos declarar um método sem contudo especificar seu corpo, dizendo-o abstrato. Isto funciona como uma espécie de lembrete para que alguma classe derivada complete a declaração fornecendo um corpo. Assim sendo, uma classe que contenha um método abstrato, ou que seja derivada de alguma classe que contenha um método abstrato mas não complete sua declaração, não pode ser instanciada. O uso da palavra-chave abstract é opcional, isto é, as duas declarações seguintes são equivalentes: abstract void print(); void print();
  • final : Especifica que nenhuma classe derivada pode alterar ou redefinir este método. Um método declarado como final deve ser obrigatóriamente seguido de um corpo.
  • native : Declara apenas o cabeçalho sem corpo, como no caso de abstract. Porém, esta especificação designa um método que implementado em outra linguagem como C++, por exemplo.
  • synchronized : Esta declaração é usado para desenvolver o programa de processamento concorrente. Seu propósito é impedir que dois métodos executando concorrentemente acessem os dados de uma classe ao mesmo tempo. synchromized especifica que se um método estiver acessando o dado, outros que também desejem acessá-lo têm que esperar.

Tipo de Valor de Retorno:

O tipo de valor de retorno é especificado por uma palavra chave ou nome de classe na declaração do método, estabelecendo o valor que ele pode devolver.

// Classe de números complexos class Complexo { double x, y; // parte real e complexo, respectivamnte public double Re() { // retorna a parte real return x; } public double Im() { /retorna a parte imaginaria return y; } public Complexo Vezes(Complexo c) { Complexo resultado; resultado.x = x * c.x - y * c.y; resultado.y = x * c.y + y * c.x; return resultado; } public void print() { System.out.println("(" + x + " + " + y + "i)"); } } public class Teste { public static void main(String args[]) {

float, etc), visto no tipo de dados, o método pode alterar o parâmetro a vontade que não influencia no valor externo.

Para ilustrar, veja o exemplo a seguir:

// classe de inteiro class inteiro { public int i; } // classe principal public class TestPar { // método que altera o valor do parametro int // este metodo deve ser static, pois sera chamado // pelo metodo main() que e static static void MudaInt(int k) { System.out.println("MudaInt: valor de k e " + k); k += 2; System.out.println("MudaInt: valor de k e apos incremento e " + k); } // método que altera o valor do parametro inteiro // este metodo deve ser static, pois sera chamado // pelo metodo main() que e static static void MudaInteiro(inteiro k) { System.out.println("MudaInteiro: valor de k e " + k.i); k.i += 2; System.out.println("MudaInteiro: valor de k e apos incremento e " + k.i); } // main() do TestPar public static void main(String args[]) { int i; inteiro n = new inteiro(); i = 2; n.i = 3; System.out.println("Valores originais:"); System.out.println("Valor de i e "+i); System.out.println("Valor de n e "+n.i); MudaInt(i); MudaInteiro(n); System.out.println("Valores apos a chamada dos metodos:"): System.out.println("Valor de i e "+i); System.out.println("Valor de n e "+n.i); } }

A especificação public de uma variável dentro da classe, faz com que este variável seja acessado de qualquer lugar. Para especificar a variável i do objeto k , basta escrever k.i. Em geral, a variável [var] dentro do objeto [obj] do tipo classe e referenciado por [obj].[var]. Note o uso de especificação static para os métodos MudaInt() e MudaInteiro(). Esta especificação é necessaria, pois o método principal é static, e método static não pode chamar outros métodos da mesma classe que não seja static.

O exemplo acima fornece a saída:

Valores originais: Valor de i e 2 Valor de n e 3 Valores apos a chamada dos metodos: Valor de i e 2 Valor de n e 5

[anterior, índice, seguinte] Expressões são combinações ordenadas de valores, variáveis, operadores, parênteses e chamadas de métodos, permitindo realizar cálculos aritméticos, concatenar strings, comparar valores, realizar operações lógicas e manipular objetos. Sem expressões, uma linguagem de programação seria praticamente inútil. O resultado da avaliação de uma expressão é em geral um valor compatível com os tipos dos dados que foram operados. A maneira como uma expressão é avaliada (ou calculada) obdece as mesmas regras familiares da Matemática. A regra mais simples é a da associatividade. Quando um mesmo operador aparece mais de uma vez em uma expressão, como em a+b+c , então o operador mais à esquerda é avaliado primeiro e em seguida o da direita, e assim por diante. Esta seria então equivalente a ((a+b)+c).

Precedência

Há situações em que é necessário juntar operadores diferentes numa mesma expressão. Nesse caso a associatividade não se aplica mais trivialmente. Nesse caso como descobrir quais são os operandos de um operador, e quais operadores são avaliados primeiro? A resposta está na precedência dos operadores. Por exemplo, excrevendo a+bc* , somos levados naturalmente a multiplicar primeiro b com c e em seguida o somar o produto com a. Isto porque a multiplicação tem precedência sobre a adição. A precedência é então um conjunto de regras que permitem determinar quais são os operandos de um dado operador. Como a linguagem Java é rica em operadores, alguns pouco familiares, precisamos conhecer a precedência desses operadores. Na tabela a seguir, está indicada a pecedência dos operadores comumente usados em Java. A tabela apresenta os operadores ordenados da maior precedência para a menor. Observe que, existem alguns operadores que naturalmente não requerem preocupação quanto à sua precedência, devido a forma como são empregados.

Operador Descrição

. [] () ( tipo )

Máxima precedência: separador, indexação, parâmetros, conversão de tipo

Operador unário: positivo, negativo, negação (inversão bit a bit), não (lógico), incremento, decremento

  • / % Multiplicação, divisão e módulo (inteiros)
    • Adição, subtração

<<

Translação (bit a bit) à esquerda, direita sinalizada, e direita não sinalizada (o bit de sinal será 0)

Operador relacional: menor, menor ou igual, maior ou igual, maior

== != Igualdade: igual, diferente

& Operador lógico e bit a bit

^ Ou exclusivo ( xor ) bit a bit