57547801-scjp

407
SCJP Sun Certified Java Programmer Leonardo Mota

Upload: andre-souza

Post on 14-Aug-2015

30 views

Category:

Documents


13 download

TRANSCRIPT

Page 1: 57547801-Scjp

SCJPSun Certified Java Programmer

Leonardo Mota

Page 2: 57547801-Scjp

2

Objetivos

Declarar classes e interfaces; Declarar métodos, construtores e variáveis de

instância e de classe utilizando os modificadores de visibilidade;

Declarar tipos primitivos, variáveis e arraysutilizando identificadores permitidos;

Declarar enums; Utilizar a convenção JavaBeans de nomenclatura Utilizar var-args;

Page 3: 57547801-Scjp

3

Identificadores legais

Os identificadores devem começar com uma letra, $, ou underscore ( _ )

Os identificadores não podem começar com um número Após o primeiro caracter, são permitidos letras, $, _, ou números; Não há limite de tamanho para o identificador; Palavras reservadas não são permitidas como identificadores:

abstract, boolean, break, byte, case, catch, char, class, const, continue, default, do,double, else, extends, final, finally, float, for, goto, if, implements, import,instanceof, int, interface, long, native, new, package, private, protected, public,return, short, static, strictfp, super, switch, synchronized, this, throw, throws,transient, try, void, volatile, while, assert (Java 1.4) e enum (Java 5)

Identificadores em Java são case-sensitive: valor e VALOR sãoidentificadores diferentes

Page 4: 57547801-Scjp

4

Identificadores legais

Declarações válidas:int _b;int $r;int ______6_s;int _$;int identificador_bem_extenso_para_a_minha_variavel;

Declarações ilegais:int :g;int -t;int e#;int .q;int 2k;

Page 5: 57547801-Scjp

5

Convenções da Sun

Classes e interfaces Primeira letra maiúscula

A primeira letra de cada palavra que forma o identificador também em maiúscula (formato “camelCase”)

Usar substantivos para classes e adjetivos para interfaces

Exemplo: NotaFiscal

Funcionario

FileWriter

Serializable

Page 6: 57547801-Scjp

6

Convenções da Sun

Métodos Primeira letra minúscula Formato “camelCase” Usar verbo+substantivo

getValorsetAlturacalculaFatorial

Variáveis Primeira letra minúscula Formato “camelCase”

nomeFuncionarioxmlComponentumFuncionario

Page 7: 57547801-Scjp

7

Convenções da Sun

Constantes TODOS os caracteres em maiúsculas

Separados por underscore ( _ )VALOR_MAXIMO

VALOR_MINIMO

Page 8: 57547801-Scjp

8

Convenções da Sun

No exame as questões costumam respeitar apenas as convenções de nomenclatura

Código aderente às normas da Sun:class Teste {

private int i;public static void main(String[] args) {

Teste t = new Teste();for (int x = 100; x > 0; --x) {

System.out.print(x + " ");}

}}

Código na questão:class Teste {

private int i;public static void main(String[] args) {

Teste t = new Teste();for(int x=100; x>0; --x) { System.out.print(x + " "); }

} }

Page 9: 57547801-Scjp

9

Padrão JavaBeans

Especifica um padrão de nomeclatura para métodos quemanipulam as propriedades das classes: getters (recuperam ovalor) e setters (modificam o valor)

Para atributos não booleanos, o prefixo do método getter deveser get. Exemplo: getTamanho()

Para atributos booleanos, o prefixo pode ser get ou is. Exemplo: isCarnivoro()ou getCarnivoro()

Para métodos setters, o prefixo deve ser set. Exemplo:setLargura()é um nome JavaBean válido para a propriedade largura

O nome do método é formado pelo prefixo apropriado seguidopelo nome da propriedade com a primeira letra maiúscula

Page 10: 57547801-Scjp

10

Padrão JavaBeans

Métodos setters devem ser públicos, retornando void erecebendo um argumento com o tipo da propriedade alvo:public void setCpf(String newCpf) {

cpf = newCpf;

}

Métodos getters devem ser públicos, sem argumentos, e retornam um tipo compatível com o argumento recebido pelo método setter:public String getCPF() {

return cpf;

}

Page 11: 57547801-Scjp

11

Classes

Regras para a criação de um arquivo .java Só pode haver uma única classe pública por arquivo

Caso haja uma classe pública no arquivo (pode não haver), o nome do arquivo deve bater com o nome da classe. Se no arquivo existe uma classe declarada como public classAnimal { } o nome do arquivo deve ser Animal.java

Um arquivo sem classes públicas pode ter qualquer nome (não precisa bater com o nome de nenhuma classe)

Se a classe está em um pacote (package), a declaração do pacote deve ser a primeira linha de código do arquivo, antes de qualquer import

Page 12: 57547801-Scjp

12

Classes

Regras para a criação de um arquivo .java Se há algum comando import, ele deve vir entre a

declaração do pacote e a declaração da classe. O importdeve ser a primeira linha de código do arquivo se não houver declaração de pacote. Se não houver nem declaração de pacote nem import, a declaração da classe deve ser a primeira linha de código do arquivo

A declaração do pacote e os imports são globais, afetando todas as classes presentes no arquivo

Um arquivo pode conter mais de uma classe não pública

Page 13: 57547801-Scjp

13

Classes

Declaração Declaração básica:

class Classe11 { }

Incluindo os modificadores de visibilidade:public class Classe11 { } // compila sem erros

protected class Classe11 { } // erro de compilação

private class Classe11 { } // erro de compilação

Incluindo outros modificadores permitidos:strictfp class Classe11 { }

final class Classe11 { }

abstract class Classe11 { }

Page 14: 57547801-Scjp

14

Classes

Modificadores de visibilidade Controlam o acesso às classes

Há quatro níveis de controle: Default

Public

Protected

Private

ATENÇÃO: Há apenas três modificadores!

Apenas public e default se aplicam a classes

Page 15: 57547801-Scjp

15

Classes

Acesso a classes Se o código em uma classe A acessa uma classe B (A

“enxerga” B), a classe A pode fazer as seguintes operações com B: Criar uma instância de B

Estender B (tornar-se subclasse de B)

Acessar métodos e variáveis da classe B, desde que permitido pelos respectivos modificadores

Page 16: 57547801-Scjp

16

Classes

Acesso default Ocorre quando não é especificado nenhum modificador Uma classe com acesso default somente pode ser “vista” por

classes do seu mesmo pacote O exemplo a seguir não compila:Arquivo Bebida.javapackage pack1;class Bebida {}

Arquivo Cafe.javapackage otherPack.stuff;import pack1.Bebida; // erro de compilação!class Cafe extends Bebida {}

Page 17: 57547801-Scjp

17

Classes

Acesso public Uma classe declarada como public permite que qualquer outra

classe dentro de qualquer pacote a acesse Se as classes estiverem em pacotes diferentes, é necessário o

comando import Exemplo:Arquivo Bebida.javapackage pack1;public class Bebida { }

Arquivo Cafe.javapackage otherPack.stuff;import pack1.Bebida;class Cafe extends Bebida { }

Page 18: 57547801-Scjp

18

Classes

O modificador final Uma classe declarada como final não pode ser estendida

Se a classe A é final, a linha a seguir gera erro de compilação:

class B extends A { }

O uso de final garante que todos os métodos da classe A nunca poderão ser redefinidos (impede o override)

Desvantagem: sem herança não há possibilidade de especialização

Exemplo de classe final presente na API Java : String

Page 19: 57547801-Scjp

19

Classes

O modificador final Exemplo:Arquivo Bebida.javapackage pack1;public final class Bebida { }

Arquivo Cafe.javapackage otherPack.stuff;import pack1.Bebida;class Cafe extends Bebida { } // erro de compilação!

Page 20: 57547801-Scjp

20

Classes

O modificador abstract Uma classe marcada com o modificador abstract

(classe abstrata) nunca pode ser instanciada

A classe abstrata existe apenas para ser estendida

final e abstract são inimigos!

Aplica-se quando a classe é muito genérica

Page 21: 57547801-Scjp

21

Classes

O modificador abstract Exemplo:

abstract class Automovel {private double preco;private String marca;private String modelo;private String ano;public abstract void acelera(); //métodos abstratos

terminam em ‘;’public abstract void acendeFarois();public abstract void buzina();

}

Se a classe Locadora tentar instanciar um objeto da classe Automovel…Automovel a = new Automovel(); // erro de compilação!

Page 22: 57547801-Scjp

22

Classes

O modificador abstract A presença de um único método abstrato requer que a classe seja

abstrata Uma classe pode ser abstrata sem que tenha qualquer método

abstrato Uma classe abstrata pode ter métodos não abstratos Exemplo:abstract class Automovel {

private double preco;private String marca;private String modelo;private String ano;public String getModelo() { return modelo; }}

Page 23: 57547801-Scjp

23

Interfaces

Declaração Uma interface é uma definição de um contrato das operações de

uma classe Especifica quais são as operações, e não como elas serão

executadas Exemplo:interface Voador {

void voa(); // termina com um ‘;’}

Uma interface é como se fosse uma classe 100% abstrata. O compilador “enxerga” o código da seguinte forma:

interface Voador {public abstract void voa(); // termina com um ‘;’

}

Page 24: 57547801-Scjp

24

Interfaces

Declaração Uma classe que implementa a interface Voador deve ser

declarada assim:class VoaComAsas implements Voador {

public void voa () { // public é obrigatório aqui// código fonte que sabe voar com asas}

}

O modificador abstract é permitido! As duas declarações abaixo são válidas e idênticas:

public abstract interface Dobravel { }public interface Dobravel { }

Os níveis de acesso permitidos para interfaces são default epublic

Page 25: 57547801-Scjp

25

Interfaces

Regras Todos os métodos de uma interface são implicitamente públicos e

abstratos.

Todas as variáveis declaradas em uma interface devem ser definidas como public, static, e final

Um interface não pode conter métodos estáticos

Métodos em uma interface não podem ser final, strictfp, ou native

Uma interface pode estender uma ou mais interfaces

Uma interface somente pode estender interfaces

Uma interface não pode implementar uma interface

Interfaces podem ser usadas com polimorfismo

Page 26: 57547801-Scjp

26

Interfaces

Declaração de constantes Constantes definidas em uma interface são visíveis a todas

as classes que implementam a interface Exemplo:Arquivo MyInterface.java:interface MyInterface {int MAX_SIZE = 10;void go();}Arquivo MyClass.java:class MyClass implements MyInterface {public void go() { MAX_SIZE = 35; // erro de compilação!

MAX_SIZE é read-only} }

Page 27: 57547801-Scjp

27

Atributos e métodos

Os quatro níveis de controle de acesso se aplicam a atributos e métodos: public

protected

default

private

Page 28: 57547801-Scjp

28

Atributos e métodos

Tipos de acesso Código em uma classe pode acessar um atributo ou método em

uma outra classe:class X {

public String getName() { return “X”; }}

class Y {public void useX() {X x = new X();System.out.println(“x.getName()=”+x.getName());}

}

Page 29: 57547801-Scjp

29

Atributos e métodos

Tipos de acesso Uma subclasse pode herdar um atributo ou método de sua superclasse:class A {

public String getName() { return “A”; }

}

class B extends A {

public void myMethod() {

System.out.println(“1: ”+this.getName()); // B herda de A

A a = new A();

System.out.println(“A.getName()=”+a.getName());

}

}

Quando uma subclasse herda um atributo ou método, é como se elamesma tivesse declarado esse atributo ou método.

Page 30: 57547801-Scjp

30

Atributos e métodos

Como verificar se a classe A acessa atributos e métodos da classe B Passo 1: Verificar o nível de acesso da classe B

Passo 2: Verificar o nível de acesso dos atributos e métodos da classe B

Page 31: 57547801-Scjp

31

Atributos e métodos

Acesso public Quando um atributo ou método é público, todas as outras classes,

independente do pacote onde estejam, podem acessá-lo Exemplo 1:Arquivo A.javapackage p1;import p2.*;class A {

public static void main(String[] args) {B b = new B();b.test(); // Ok porque test é público}

}Arquivo B.javapackage p2;public class B {public void test() { System.out.println("B!!"); }}

Page 32: 57547801-Scjp

32

Atributos e métodos

Acesso public Exemplo 2:Arquivo A.javapackage p1;public class A {

public String myMethod() { return “hi”; }}

Arquivo B.javapackage p2;import p1.A;class B extends A {

public void testB() {System.out.println(myMethod()); //ou então this.myMethod()}

}

Page 33: 57547801-Scjp

33

Atributos e métodos

Acesso private Atributos e métodos private somente são visíveis dentro da própria

classe que os declarou Exemplo 1:Arquivo A.javapackage p1;import p2.B;class A {

public static void main(String[] args) {B b = new B(); // Ok porque a classe B é públicab.test(); // erro de compilação: cannot find symbol

}}Arquivo B.javapackage p2;public class B {

private void test() { System.out.println("B!!"); }}

Page 34: 57547801-Scjp

34

Atributos e métodos

Acesso private Exemplo 2:Arquivo A.javapackage p1;public class A {

private String myMethod() { return “hi”; }}

Arquivo B.javapackage p1; // A e B estão no mesmo pacoteclass B extends A {

public void testB() {System.out.println(myMethod()); // erro de compilação

}}

Page 35: 57547801-Scjp

35

Atributos e métodos

Acesso protected x acesso default Um atributo/método com visibilidade default ou protected

somente pode ser acessado por classes que pertençam ao mesmo pacote

Caso o atributo/método seja protected, qualquer subclasse da classe que declarou o atributo/método pode acessá-lo (via herança), podendo a superclasse e a subclasse estarem em pacotes diferentes

Caso o atributo/método tenha visibilidade default, uma subclasse da classe que declarou o atributo/método somente pode acessá-lose estiver no mesmo pacote que a superclasse

Page 36: 57547801-Scjp

36

Atributos e métodos

Acesso protected x acesso default Exemplo:Arquivo OutraClasse.javapackage certificacao;public class OutraClasse {

void teste() { // sem modificador, visibilidade defaultSystem.out.println("OutraClasse");

}}Arquivo MinhaClasse.javapackage outroPacote;import certificacao.OutraClasse;class MinhaClasse {

public static void main(String[] args){OutraClasse o = new OutraClasse();o.teste(); // erro de compilação: método não pode ser

// acessado de fora do pacote}

}

Page 37: 57547801-Scjp

37

Atributos e métodos

Acesso protected x acesso default Exemplo:

Arquivo OutraClasse.java

package certificacao;public class OutraClasse {

protected void teste() { // visibilidade protectedSystem.out.println("OutraClasse");

}}Arquivo MinhaClasse.javapackage outroPacote;import certificacao.OutraClasse;class MinhaClasse {

public static void main(String[] args){OutraClasse o = new OutraClasse();o.teste(); // erro de compilação: método é protected}

}

Page 38: 57547801-Scjp

38

Atributos e métodos

Acesso protected Exemplo 1:Arquivo Pai.javapackage certificacao;public class Pai {

protected int x = 9; // visível a todos dentro do pacote e

// visível (herança) a classes fora do pacote

}

Arquivo Filho.javapackage outroPacote; // Pai e Filho em pacotes diferentesimport certificacao.Pai;

class Filho extends Pai {

public void teste(){

System.out.println(“valor de x: ”+x); // ok!

}

}

Page 39: 57547801-Scjp

39

Atributos e métodos

Acesso protected Exemplo 2:

Arquivo Pai.javapackage certificacao;public class Pai {

protected int x = 9; // visível a todos dentro do pacote e// visível (herança) a classes fora do pacote

}Arquivo Filho.javapackage outroPacote; // Pai e Filho em pacotes diferentesimport certificacao.Pai;class Filho extends Pai {

public void teste(){System.out.println(“valor de x: ”+x); // ok!Pai p = new Pai();System.out.println(“valor de Pai.x: ”+p.x); // erro!}

}

Page 40: 57547801-Scjp

40

Atributos e métodos

Acesso protected Quando uma subclasse de fora do pacote herda um

atributo protected, o atributo é essencialmente privado dentro da subclasse, de forma que apenas a subclasse e suas subclasses podem acessá-lo

Page 41: 57547801-Scjp

41

Atributos e métodos

Acesso default Exemplo:

Arquivo Pai.java

package certificacao;public class Pai {int x = 9; //sem modificador, visível a todos dentro do pacote}Arquivo Filho.javapackage outroPacote; // Pai e Filho em pacotes diferentesimport certificacao.Pai;class Filho extends Pai {

public void teste(){System.out.println(“valor de x: ”+x); // erro de compilação}

}

Page 42: 57547801-Scjp

42

Atributos e métodos

Acesso default Corrigindo o exemplo:Arquivo Pai.javapackage certificacao;

public class Pai {

int x = 9; // sem modificador, visível a todos dentro do pacote

}

Arquivo Filho.javapackage certificacao; // Pai e Filho no mesmo pacote

class Filho extends Pai {

public void teste(){

System.out.println(“valor de x: ”+x); // OK! x = 9

}

}

Page 43: 57547801-Scjp

43

Atributos e métodos

Outros modificadores utilizados na declaração de atributos e métodos: final

abstract

transient

synchronized

native

strictfp

static

Page 44: 57547801-Scjp

44

Modificadores aplicados a métodos

final Impede que um método seja redefinido (override) na subclasse

Exemplo:

class SuperClasse {

public final void exibeNome(){

System.out.println(“SuperClasse”);

}

}

class SubClasse extends SuperClasse { // Ok!

public void exibeNome(){

System.out.println(“SubClasse”); // erro de compilação

}

}

Page 45: 57547801-Scjp

45

Modificadores aplicados a métodos

final Impede que um argumento de um método seja

modificado dentro do método

Exemplo:

public Record getRecord (String fileName, finalint recordNumber) {}

A variável recordNumber é declarada como final e por isso não pode ter o seu valor modificado dentro do método. Ou seja, não é permitido fazer

recordNumber = novoValor

Page 46: 57547801-Scjp

46

Modificadores aplicados a métodos

abstract Um método abstrato é um método que foi declarado

mas não foi implementado

Métodos abstratos não contém código

Quando um método é abstrato em uma classe, todas as suas subclasses são obrigadas a fornecer uma implementação para ele

Exemplo:public abstract void exibeNome();

Page 47: 57547801-Scjp

47

Modificadores aplicados a métodos

abstract Uma subclasse que estende uma classe abstrata deve

implementar todos os seus métodos abstratos

Regra geral: A primeira classe concreta (não abstrata) na hierarquia deve implementar todos os métodos abstratos, de todas as classes abstratas

Page 48: 57547801-Scjp

48

Modificadores aplicados a métodos

abstract Exemplo:public abstract class Veiculo {private String tipo;

public abstract void acelera();public String getTipo() {return tipo;}

}public abstract class Carro extends Veiculo {

public abstract void acelera();public void abrePortaMalas() { // código }

}public class Audi extends Carro {

public void acelera() { // código específico do Audi, implementação obrigatória}

}

Page 49: 57547801-Scjp

49

Modificadores aplicados a métodos

abstract Um método nunca pode ser abstract e final

Um método nunca pode ser abstract e private

Um método nunca pode ser abstract e static

abstract static void calcula(); // erro de compilação!

Page 50: 57547801-Scjp

50

Modificadores aplicados a métodos

synchronized Aplica-se somente a métodos

Pode ser combinado com qualquer um dos três modificadores de acesso (ou quatro níveis de controle de acesso)

public synchronized Record getRecord(int recId) {}

native Aplica-se somente a métodos

strictfp Aplica-se a classes e a métodos, nunca a variáveis

Page 51: 57547801-Scjp

51

Construtores

Declaração:class Aluno {

protected Aluno() {} // Construtor da classe Aluno

protected void Aluno() {} // Método válido (!)

}

Um construtor nunca tem um tipo de retorno

Pode ter ou não argumentos

Todos os modificadores de acesso são permitidos

Um construtor deve ter o mesmo nome da classe

Construtores não podem ser static, final e abstract

Page 52: 57547801-Scjp

52

Variáveis

Tipos de variáveis: Primitivos

Referências

Arrays

Page 53: 57547801-Scjp

53

Variáveis

Tipos primitivos: Podem ser variáveis de classe (estáticas), de instância,

parâmetros de métodos, tipos de retorno e variáveis locais

Exemplos:byte b;

boolean hasNext;

int x, y, z; // declara três variáveis int

Page 54: 57547801-Scjp

54

Variáveis

Tipos primitivos: Todos os primitivos são signed

Page 55: 57547801-Scjp

55

Variáveis

Tipos primitivos: Ranges de valores

Page 56: 57547801-Scjp

56

Variáveis

Referências: Uma variável de referência é utilizada para acessar um

objeto Podem ser variáveis de classe (estáticas), de instância,

parâmetros de métodos, tipos de retorno e variáveis locais

Exemplos:Object o;Animal meuAnimal;String s1, s2, s3; // declara três variáveis String

Page 57: 57547801-Scjp

57

Variáveis

Arrays: Todo array é um objeto em Java

Um array pode armazenar tipos primitivos ou referências para objetos

Podem ser variáveis de classe (estáticas), de instância, parâmetros de métodos, tipos de retorno e variáveis locais

Exemplos:int[] chaves; // array de primitivos

Animal listaAnimais[]; // array de referências (a objetos da classe animal)

String[][][] multiDimensionalArray1;

String[] multiDimensionalArray2[]; //permitido!

Page 58: 57547801-Scjp

58

Variáveis

final Uma variável declarada com o modificador final nunca mais pode ser

modificada após ter sido inicializada

Para primitivos, significa que o valor da variável não pode mudar

Para referências, significa que a variável não pode “apontar” para outroobjeto diferente do qual foi especificado na sua inicialização

transient Indica que o atributo da classe não será considerado durante a

serialização

Somente pode ser aplicado a variáveis de instância

volatile Somente pode ser aplicado a variáveis de instância

Page 59: 57547801-Scjp

59

Modificador static

Um atributo ou método estático existe independente de qualquer instância da classe

Para utilizar um atributo ou método estático não é necessário criar uma nova instância. Por isso são chamados atributos ou métodos de classe

Não importa quantas instâncias da classe tiverem sido criadas, há somente uma cópia do atributo estático na memória

Construtores, classes, interfaces e variáveis locais não podem ser declaradas como static!

Page 60: 57547801-Scjp

60

Enums

Permitem especificar um domínio de valores para uma variável Declaração básica:enum DiaDaSemana{ SEGUNDA, TERCA, QUARTA, QUINTA,

SEXTA, SABADO, DOMINGO };

SEGUNDA, TERCA, QUARTA, etc. são do tipo DiaDaSemana

Como obter um dia da semana?

DiaDaSemana d = DiaDaSemana.SEGUNDA;

Page 61: 57547801-Scjp

61

Enums

Enums podem ser declarados como atributos da classe ou então fora da classe

Exemplo de enum fora da classe:class Calendario {DiaDaSemana d;}public class EnumFora {

public static void main(String[] args) {Calendario c = new Calendario();c.d = DiaDaSemana.SEGUNDA;System.out.println(c.d);}

}enum DiaDaSemana{SEGUNDA, TERCA, QUARTA, QUINTA, SEXTA, SABADO, DOMINGO}

Page 62: 57547801-Scjp

62

Enums

Exemplo de enum como atributo da classe:class Calendario2 {

enum DiaDaSemana

{SEGUNDA, TERCA, QUARTA, QUINTA, SEXTA, SABADO, DOMINGO}; // ‘;’ opcional

DiaDaSemana d;

}

public class EnumAtributo {

public static void main(String[] args) {

Calendario2 c = new Calendario2();

c.d = Calendario2.DiaDaSemana.SEGUNDA; // nome da classe é necessário

System.out.println(c.d);

}

}

Enums admitem apenas nível de acesso public oudefault (igual a classes)

Page 63: 57547801-Scjp

63

Enums

Construtores, métodos e variáveis no enumenum TamanhoPizza {MEDIA(4), GRANDE(8), GIGANTE(16);

TamanhoPizza(int fatias) { // construtor do enumthis.fatias = fatias; }private int fatias; // variável de instância que cada valor do enumpossuipublic int getFatias() { return fatias; }

}class Pizza {

TamanhoPizza fatias; // cada Pizza tem o seu enum de tamanhopublic static void main(String[] args) {

Pizza p1 = new Pizza();p1.fatias = TamanhoPizza.MEDIA;Pizza p2 = new Pizza();p2.fatias = TamanhoPizza.GIGANTE;System.out.println(p1.fatias.getFatias()); // 4System.out.println(p2.fatias.getFatias()); // 16

}}

Page 64: 57547801-Scjp

64

Var-args

Os métodos com var-args podem receber um número variável de argumentos

Para declarar um var-arg, definir o tipo, inserir ‘...’ seguido de um espaço e então o identificador

Só pode haver um único parâmetro var-arg no método O parâmetro var-arg deve ser o último definido na assinatura do

método Exemplos:void calcula(int... x) { // pode receber de 0 a N ints como

parâmetroSystem.out.println(x[0]);

}void calcula2(char c, int... x) {}void calcula3(Animal... animais) {} // recebe de 0 a N Animais

Page 65: 57547801-Scjp

65

Objetivos

Descrever encapsulamento, coesão e acoplamento

Utilizar polimorfismo

Implementar construtores e utilizar construtores de superclasse e sobrecarregados (overloaded)

Utilizar relacionamentos IS-A (é um) e HAS-A (tem um)

Declarar, inicializar e utilizar atributos e métodos

Utilizar sobrecarga (overloading) e sobrescrita (overriding)

Identificar tipos de retorno permitidos em métodos

Page 66: 57547801-Scjp

66

Encapsulamento

Benefícios da Orientação a Objetos: Flexibilidade Manutenibilidade

O programador deve codificar usando boas práticaspublic class MaPraticaOO { // Versao 1

public int altura;public int largura;...

}public class ExploraMaPraticaOO {

public static void main (String [] args) {MaPraticaOO b = new MaPraticaOO();b.altura = -5; // permitido, porem ruim}

}

Page 67: 57547801-Scjp

67

Encapsulamento

Como melhorar o código?public class MaPraticaOO { // Versao 2

private int altura;private int largura;public void setAltura(int alt) { this.altura = alt; }...

}public class UsaMaPraticaOO {

public static void main (String [] args) {MaPraticaOO b = new MaPraticaOO();b.setAltura(-5); // o atributo somente pode ser modificado atraves do metodo}

}

Os usuários da versão 2 não sabem mais utilizar a classe...

Page 68: 57547801-Scjp

68

Encapsulamento

O principal benefício é a capacidade de fazermudanças no código sem “quebrar” o código dos outros

Os detalhes da implementação ficam escondidos atrás de um conjunto de métodos

É a definição de uma API da sua classe

É possível alterar um método da API de forma que o mundo exterior não seja afetado

Page 69: 57547801-Scjp

69

Encapsulamento

Alcançando o encapsulamento: Mantenha as variáveis de instância protegidas por um

modificador de visibilidade (private)

Implemente métodos públicos para acesso aos atributos da classe, para forçar que o código chamador use esses métodos ao invés de acessar os atributos diretamente

Utilizar a convenção JavaBeans de nomenclatura

Page 70: 57547801-Scjp

70

Encapsulamento

Page 71: 57547801-Scjp

71

Relacionamento IS-A e HAS-A

IS-A Relacionamento baseado em herança ou implementação de

interface

É uma maneira de dizer “esta coisa é um tipo daquela coisa”

Exemplos: Manga Larga Marchador é um Cavalo (“é um tipo de Cavalo”)

Audi é um Carro (“é um tipo de Carro”)

Cenoura é um Vegetal (“é um tipo de Vegetal”)

Pentágono é um Polígono (“é um tipo de Polígono”)

Page 72: 57547801-Scjp

72

Relacionamento IS-A e HAS-A

É implementado em Java através das palavras-chave extends (herança) e implements(implementação de interface)

public class Car { }

public class Audi extends Car { }

public inteface Voador {

void voa();

}

public class Morcego implements Voador {

public void voa() { // código que faz o morcego voar }

}

Page 73: 57547801-Scjp

73

Relacionamento IS-A e HAS-A

Exemplo de uma hierarquia de classes

public class Vehicle { ... }

public class Car extends Vehicle { ... }

public class Subaru extends Car { ... }

"Car extends Vehicle" == "Car IS-A Vehicle."

"Subaru extends Car" == "Subaru IS-A Car."

Page 74: 57547801-Scjp

74

Relacionamento IS-A e HAS-A

No jargão de OO, temos: Vehicle é a superclasse de Car.

Car é a subclasse de Vehicle.

Car é a superclasse de Subaru.

Subaru é a subclasse de Vehicle.

Car herda de Vehicle.

Subaru herda tanto de Vehicle quanto de Car.

Subaru é derivada de Car.

Car é derivada de Vehicle.

Subaru é derivada de Vehicle.

Subaru é um sub-tipo de Vehicle e de Car ao mesmo tempo.

Page 75: 57547801-Scjp

75

Relacionamento IS-A e HAS-A

É correto dizer “Subaru IS-A Vehicle” ? Sim!

Podemos dizer que uma classe “é do tipo de” qualquer classe que venha acima na sua árvore de herança

Ou seja, o teste do IS-A será verdadeiro mesmo quando a herança for indireta

A expressão (Subaru instanceof Vehicle) retorna verdadeiro se e somente se “Subaru IS-AVehicle” for verdadeiro

Page 76: 57547801-Scjp

76

Relacionamento IS-A e HAS-A

HAS-A Significa “tem um” É baseado em utilização ao invés de herança Dizemos que “classe A HAS-A B” se código na classe

A tem uma referência para uma instância da classe B Exemplo:public class Animal { }public class Cavalo extends Animal {//Cavalo IS-A Animal

private Sela umaSela; // Cavalo HAS-A Sela}

A classe Cavalo tem uma variável de instância do tipo Sela, e pode invocar métodos da classe Sela

Page 77: 57547801-Scjp

77

Relacionamento IS-A e HAS-A

public class Animal { }

public class Cavalo extends Animal {

private Sela umaSela;

...

public void ajustaSela() {

umaSela.ajustaSela(); // utiliza a referência para a

// classe Sela para delegar o

// ajuste da Sela

}

}

public class Sela {

public void ajustaSela() {

// código que sabe como se ajusta uma sela

}

}

Page 78: 57547801-Scjp

78

Relacionamento IS-A e HAS-A

Relacionamentos HAS-A permitem que as classes sejam especialistas

Qualquer outra classe do sistema que precisar docomportamento da Sela não precisa implementar esse código, bastando utilizar a classe Sela (especialista)

Page 79: 57547801-Scjp

79

Polimorfismo

Toda classe em Java estende a classe java.lang.Objectclass Test { //inserir extends Object apos Test nao seria um erro

public static void main(String [] args) {Test t1 = new Test();Test t2 = new Test();if (!t1.equals(t2)) // metodo equals() herdado de Object

System.out.println("they're not equal");if (t1 instanceof Object)System.out.println("t1's an Object");}

}

O programa imprime:they're not equalt1's an Object

Page 80: 57547801-Scjp

80

Polimorfismo

Dada a classe

class Pessoa {}

Para qualquer objeto p da classe Pessoa: p IS-A Pessoa == verdadeiro (p instanceof Pessoa)

p IS-A Object == verdadeiro (p instanceof Object)

Page 81: 57547801-Scjp

81

Polimorfismo

Variáveis de referência e objetos Os objetos em Java são acessados através de variáveis

de referênciaPessoa p = new Pessoa (“Joao”);

A linha acima declarou uma variável p do tipo Pessoa e atribuiu a p uma referência a um novo objeto na memória

p é uma variável de referência para a Pessoa “Joao”

Page 82: 57547801-Scjp

82

Polimorfismo

Fatos sobre as variáveis de referência: Uma variável de referência pode ter o seu valor alterado, passando a

“apontar” para outro objeto

O tipo de uma variável de referência determina os métodos que podem ser invocados no objeto que ela referencia

Uma variável de referência pode referenciar qualquer sub-tipo do tipo declarado

Uma variável de referência pode ser declarada com um tipo de classe ou um tipo de interface. Se o seu tipo for uma interface, a variável pode fazer referência a qualquer objeto que implemente aquela interface

Page 83: 57547801-Scjp

83

Polimorfismo

class GameShape {public void displayShape() {System.out.println(“mostrando elemento");}...

}class PlayerPiece extends GameShape {

public void movePiece() {System.out.println("movendo peca");}...

}class TilePiece extends GameShape {

public void getAdjacent() {System.out.println("obtendo forma adjacente");}...

}

Page 84: 57547801-Scjp

84

Polimorfismo

public class TestShapes {

public static void main (String[] args) {

PlayerPiece player = new PlayerPiece();

TilePiece tile = new TilePiece();

doShapes(player);

doShapes(tile);

}

public static void doShapes(GameShape shape) {

shape.displayShape(); // todo GameShape ou quem herda de

// GameShape possui o método

// displayShape()

}

}

O programa tem a seguinte saída:

mostrando elemento

mostrando elemento

Page 85: 57547801-Scjp

85

Polimorfismo

É também válido fazer:public class TestShapes {

public static void main (String[] args) {GameShape player = new PlayerPiece();GameShape tile = new TilePiece();doShapes(player);doShapes(tile);}public static void doShapes(GameShape shape) {shape.displayShape();}

}

Relembrando: Uma variável de referência pode “apontar” para qualquer objeto do seu

mesmo tipo ou então pode referenciar qualquer sub-tipo do tipo declarado

Page 86: 57547801-Scjp

86

Polimorfismo

Alterando a classe PlayerPiece:class GameShape {

public void displayShape() {System.out.println(“mostrando elemento");}

}public interface Animavel {

public void anima();}class PlayerPiece extends GameShape implements Animavel {

public void movePiece() {System.out.println("movendo peca");}public void anima() { System.out.println(“animando...”); }

}

Page 87: 57547801-Scjp

87

Polimorfismo

PlayerPiece agora passa no teste IS-A para a classeGameShape e a interface Animavel

As quatro declarações abaixo são válidas:PlayerPiece player = new PlayerPiece();

Object o = player;

GameShape shape = player;

Animavel a = player;

No código acima, há apenas um objeto e quatro variáveis de referência

Page 88: 57547801-Scjp

88

Polimorfismo

Enquanto o compilador somente conhece o tipo da variável dereferência, a Máquina Virtual Java (JVM) em tempo de execução conhece o tipo real do objeto

Ou seja, se chamarmos o método displayShape() em um objeto PlayerPiece utilizando uma variável do tipoGameShape, a JVM saberá em tempo de execução que trata-se de um objeto PlayerPiece

Se PlayerPiece sobrescrevesse o método displayShape(override), a JVM invocaria o método definido em PlayerPiece

Em tempo de execução apenas os métodos de instância sãodinamicamente selecionados com base no tipo real do objeto

Page 89: 57547801-Scjp

89

Sobrescrita de métodos (Override)

Sobrescrever é redefinir na subclasse o comportamento do método originalda superclasse

Dessa forma a subclasse pode definir um comportamento específico para oseu uso

Exemplo: Cavalo sobrescreve o método come da classe Animalpublic class Animal {

public void come() {

System.out.println(“Animal generico comendo");

}

}

class Cavalo extends Animal {

public void come() {

System.out.println(“Cavalo comendo feno e cenoura");

}

}

Page 90: 57547801-Scjp

90

Sobrescrita de métodos (Override)

public class Animal {public void come() {System.out.println(“Animal generico comendo");}

}class Cavalo extends Animal {

public void come() {System.out.println(“Cavalo comendo feno e cenoura");}public void relincha() {}

}public class TestaAnimais {

public static void main (String [] args) {Animal a = new Animal();Animal b = new Cavalo(); //var Animal, mas objeto Cavaloa.come(); // Executa o metodo come() da classe Animalb.come(); // Executa o metodo come() da classe Cavalo}

}

Page 91: 57547801-Scjp

91

Sobrescrita de métodos (Override)

Se utilizamos uma variável do tipo Animal ocompilador somente permite utilizar métodos da classe AnimalAnimal c = new Cavalo();

c.relincha(); // erro de compilação! Animal não tem o

método relincha

Através do Polimorfismo, é possível usar um supertipo abstrato (incluindo uma interface) para referenciar

Page 92: 57547801-Scjp

92

Sobrescrita de métodos (Override)

Atenção: O método que está sobrescrevendo (na subclasse) não pode terum modificador de acesso mais restritivo do que o método original (dasuperclasse)

public class Animal {public void come() {System.out.println(“Animal generico comendo"); }

}class Cavalo extends Animal {

private void come() { // erro de compilação!System.out.println(“Cavalo comendo feno e cenoura"); }public void relincha() {}

}public class TestaAnimais {

public static void main (String [] args) {Animal a = new Animal();Animal b = new Cavalo(); //var Animal, mas objeto Cavaloa.come(); // Executa o metodo come() da classe Animalb.come(); // Executa o metodo come() da classe Cavalo}

}

Page 93: 57547801-Scjp

93

Sobrescrita de métodos (Override)

O contrato da superclasse Uma variável de referência do tipo Animal pode

sempre “apontar” para uma instância da classe Cavalo, pois Cavalo é um Animal (“Cavalo IS-A Animal” é verdadeiro)

Quem possuir uma referência da classe Animal para uma instância de Cavalo é livre para chamar todos os métodos de Animal, independente se Cavalo sobrescreve algum método ou não

Page 94: 57547801-Scjp

94

Sobrescrita de métodos (Override)

Regras A lista de argumentos deve bater exatamente. Se não bater,

pode ocorrer overload O tipo de retorno deve ser o mesmo ou um subtipo do tipo

de retorno original O nível de acesso só pode ser menos restritivo do que no

método da superclasse Se a subclasse está no mesmo pacote que a superclasse,

pode sobrescrever os métodos que não sejam private ou final. Já uma subclasse em um pacote diferente dasuperclasse pode sobrescrever os métodos public ouprotected (e não final)

Page 95: 57547801-Scjp

95

Sobrescrita de métodos (Override)

Regras O método que está sobrescrevendo pode lançar qualquer runtime

exception (ditas unchecked), independente se o método original declara ou não a exceção

O método que está sobrescrevendo não pode lançar exceções (checked exceptions) novas ou mais genéricas do que as que foram declaradas no método original.

O método que está sobrescrevendo pode lançar menos exceções do que o método original, exceções mais específicas ou então não lançar nenhuma

Não é permitido sobrescrever um método final ou static

Page 96: 57547801-Scjp

96

Sobrescrita de métodos (Override)

Atenção: Se um método não pode ser herdado, não existe overridepublic class TestaAnimais {

public static void main (String [] args) {Cavalo c = new Cavalo();c.come(); // Ilegal pois Cavalo não herda come()}

}class Animal {

private void come() {System.out.println(“Animal generico comendo");}

}class Cavalo extends Animal { }

Page 97: 57547801-Scjp

97

Sobrescrita de métodos (Override)

Invocando o método sobrescrito (da superclasse) de dentro do método da subclasse

public class Animal {public void come() { }public void imprimeAnimal() {// Codigo que imprime o Animal}

}class Cavalo extends Animal {

public void imprimeAnimal() {// Utiliza o codigo da classe Animal, e depois faz mais coisassuper.imprimeAnimal(); // Invoca o codigo da superclasse// E depois imprime dados específicos do Cavalo}

}

Page 98: 57547801-Scjp

98

Sobrescrita de métodos (Override)

Dada a seguinte classe:public class Animal {

public void come() { }

}

São exemplos de overrides inválidos: private void come() { }

Problema: Nível de acesso é mais restritivo

public void come() throws IOException { }

Problema: Declara uma exceção (checked) não definida no método dasuperclasse

public void come(String comida) { }

Problema: A lista de argumentos mudou (é na verdade um overload)

public String come() { }

Problema: Tipo de retorno mudou (também não é um overload)

Page 99: 57547801-Scjp

99

Sobrecarga de métodos (Overload)

Permite que um método com o mesmo nome de um já existente seja criado, porém com argumentos distintos e opcionalmente com outrotipo de retorno

Regras: Deve mudar a lista de argumentos (obrigatório) Pode mudar o tipo de retorno Pode mudar o modificador de visibilidade Pode declarar novas exceções ou exceções mais

genéricas

Page 100: 57547801-Scjp

100

Sobrecarga de métodos (Overload)

Um método pode ser sobrecarregado dentro da mesma classe ou em uma subclasse

Exemplo:public class A {

public void m(int i) {}

}

class B extends A {

public void m(String s) {} // Não é override!

}

No exemplo anterior, dois métodos com o mesmo nome, mas em classes diferentes, estão sobrecarregados.

Page 101: 57547801-Scjp

101

Sobrecarga de métodos (Overload)

Dado o método: public void changeSize(int size, String name, float

pattern) { }

São exemplos de overloads válidos: public void changeSize(int size, String name) { }

public int changeSize(int size, float pattern) { }

public void changeSize(float pattern, String name)throws IOException { }

Page 102: 57547801-Scjp

102

Sobrecarga de métodos (Overload)

E quando os parâmetros forem variáveis de referência?class Animal { }class Cavalo extends Animal { }class UsaAnimais {

public void fazAlgo(Animal a) {System.out.println(“Entrei na versao com arg Animal");}

public void fazAlgo(Cavalo c) {System.out.println("Entrei na versao com arg Cavalo"); }

public static void main (String [] args) {UsaAnimais ua = new UsaAnimais();Animal animalObj = new Animal();Cavalo cavaloObj = new Cavalo();ua.fazAlgo(animalObj);ua.fazAlgo(cavaloObj);}

}

Ao rodarmos o exemplo, é produzida a saída:Entrei na versao com arg AnimalEntrei na versao com arg Cavalo

Page 103: 57547801-Scjp

103

Sobrecarga de métodos (Overload)

E se na chamada ao método fazAlgo for passada como parâmetro uma referência do tipo Animal para um objeto da classe Cavalo?

Animal animalRefObjCavalo = new Cavalo();

ua.fazAlgo(animalRefObjCavalo);

Page 104: 57547801-Scjp

104

Sobrecarga de métodos (Overload)

Ao rodarmos o exemplo, é produzida a saída:

Entrei na versao com arg Animal

Mesmo que em tempo de execução o objeto seja um Cavalo e não um Animal, a escolha de que método será invocado é feita em tempo de compilação e não dinamicamente em tempo de execução

O tipo da variável de referência determina o método que será invocado

Page 105: 57547801-Scjp

105

Sobrecarga de métodos (Overload)

Sobrecarga, Sobrescrita e Polimorfismopublic class Animal {

public void come() {System.out.println(“Animal generico comendo");

}}public class Cavalo extends Animal {

public void come() {System.out.println(“Cavalo comendo feno");

}public void come(String s) {

System.out.println(“Cavalo comendo " + s);}

}

Page 106: 57547801-Scjp

106

Sobrecarga de métodos (Overload)

Sobrecarga, Sobrescrita e Polimorfismo

Page 107: 57547801-Scjp

107

Cast de Variáveis de Referência

Podemos usar uma variável de referência de um tipo mais genérico para referenciar um objeto de um tipo mais específico (Animal a = new Cao())

O que acontece se quisermos usar a referência a para invocar um método que é exclusivo da classe Cao (pois sabemos que é um cão)?

Exemplo:class Animal {

void emiteSom() {System.out.println(“som generico"); }}class Cao extends Animal {

void emiteSom() {System.out.println(“latido"); }void fingeDeMorto() { System.out.println(“deita"); } }

class CastTest2 {public static void main(String [] args) {Animal [] a = {new Animal(), new Cao(), new Animal() };for(Animal animal : a) {animal.emiteSom();if(animal instanceof Cao) {animal.fingeDeMorto();// tenta executar um comportamento de Cao}

}}}

Page 108: 57547801-Scjp

108

Cast de Variáveis de Referência

O código do exemplo anterior não compila: A classe Animal não define o método fingeDeMorto!

Erro de compilação: cannot find symbol Código corrigidoclass Animal {

void emiteSom() {System.out.println(“som generico"); }}class Cao extends Animal {

void emiteSom() {System.out.println(“latido"); }void fingeDeMorto() { System.out.println(“deita"); } }

class CastTest2 {public static void main(String [] args) {Animal [] a = {new Animal(), new Cao(), new Animal() };for(Animal animal : a) {animal.emiteSom();if(animal instanceof Cao) {Cao c = (Cao) animal; // faz o cast da var. de referenciac.fingeDeMorto(); }

}}}

Page 109: 57547801-Scjp

109

Cast de Variáveis de Referência

Antes de chamar o método específico da classeCao, precisamos criar uma variável de referência do tipo Cao para “apontar” para o objeto Cao

Somente através de uma variável do tipo Caoconseguimos acessar os métodos exclusivos de um objeto Cao

A operação é chamada de downcast, pois a partir de um tipo mais genérico (Animal) obtivemos um tipo mais específico (Cao)

Page 110: 57547801-Scjp

110

Cast de Variáveis de Referência

Atenção: O compilador sempre confia no programador!class Animal { }class Cao extends Animal { }class Test {

public static void main(String [] args) {Animal animal = new Animal();Cao c = (Cao) animal; // compila mas falha em tempo de execução: ClassCastException}

}

O compilador apenas verifica se as duas classes envolvidas nocast pertencem à mesma árvore de herança

Animal animal = new Animal();Cao c = (Cao) animal;String s = (String) animal; // erro de compilação: inconvertible

types

Page 111: 57547801-Scjp

111

Cast de Variáveis de Referência

Quando saímos de um tipo mais específico para um tipo genérico estamos fazendo upcast

É uma operação que restringe o acesso ao objeto em questão, pois o tipo genérico não conhece os métodos exclusivos do tipo específico

O upcast funciona de modo implícito. Exemplo:class Animal { }class Cao extends Animal { }class Test {

public static void main(String [] args) {Cao c = new Cao();Animal a1 = c; // upcast ok, cast implicitoAnimal a2 = (Animal) c; // upcast ok, cast explicito}

}

Page 112: 57547801-Scjp

112

Tipos de retorno

A partir do Java 5, é permitido mudar o tipo de retorno no método dasubclasse contanto que o tipo seja um subtipo do tipo de retorno declarado no método da superclasse (que está sendo sobrescrito)

É o chamado retorno covariante Exemplo:class Alpha {

Alpha fazAlgo(char c) {return new Alpha();}

}class Beta extends Alpha {

Beta fazAlgo(char c) {//sobrescrevendo o método da classe Alphareturn new Beta(); // OK, Beta é um subtipo de Alpha}

}

Page 113: 57547801-Scjp

113

Tipos de retorno

Regras: null pode ser retornado em um método que retorne uma referência para um

objeto. Exemplo:public Button doStuff() {

return null;}

Um array pode ser um tipo de retorno. Exemplo:public String[] go() {

return new String[] {"Fred", "Barney", "Wilma"};}

Um método que retorna um tipo primitivo pode retornar qualquer valor que possa ser implicitamente convertido para o tipo declarado. Exemplo:

public int foo() {

char c = 'c';return c; // char “cabe” em um int}

Page 114: 57547801-Scjp

114

Tipos de retorno

Regras (continuação): Um método que retorna um tipo primitivo pode retornar

qualquer valor que possa ser explicitamente convertido para o tipo declarado. Exemplo:public int foo () {

float f = 32.5f;

return (int) f;

}

Page 115: 57547801-Scjp

115

Tipos de retorno

Regras (continuação) Um método que retorna uma referência para um objeto pode

retornar qualquer tipo de objeto que possa ser implicitamente convertido para o tipo declarado.

Exemplo:public Animal getAnimal() {

return new Cavalo(); // Cavalo extends Animal

}

Page 116: 57547801-Scjp

116

Construtores e instanciação

Para criar um objeto em Java é necessário invocar o seu construtor

Sempre que utilizamos a palavra-chave new estamos indicando que queremos executar o construtor do objeto

Dois pontos chave: Um construtor não tem tipo de retorno

O nome do construtor deve bater exatamente com o nome da classe

Tipicamente nos construtores inicializamos o estado do objeto (atribuindo valores às suas variáveis de instância)

Page 117: 57547801-Scjp

117

Construtores e instanciação

Exemplo:class Foo {int size;String name;

Foo(String name, int size) {this.name = name;this.size = size;

}}

Invocando o construtor:Foo f = new Foo(); // Não compilaFoo f = new Foo("Fred", 43); // Ok, argumentos batem com o

construtor

Page 118: 57547801-Scjp

118

Construtores e instanciação

O que realmente acontece quando executamos a linha de código

Cavalo c = new Cavalo();

Dado que Cavalo estende Animal e Animal estende Object?1. O construtor de Cavalo é chamado. Todo construtor invoca o construtor da sua superclasse com uma

chamada (implícita) a super(), a não ser que o construtor invoque um construtor sobrecarregado damesma classe

2. O construtor de Animal é chamado (Animal é superclasse de Cavalo)

3. O construtor de Object é chamado (Object é superclasse de todas as classes, de forma que a classeAnimal estende Object mesmo que não seja digitado "extends Object" na declaração da classe. Éimplícito). Nesse ponto estamos no topo da pilha de execução

4. As variáveis de instância de Object são inicializadas com seus valores explícitos, que foram atribuídos na declaração das variáveis, como "int x = 27", onde "27" é o valor explícito da variável de instância

5. O construtor de Object chega ao fim.

6. As variável de instância de Animal são inicializadas com seus valores explícitos

7. O construtor de Animal chega ao fim

8. As variáveis de instância de Cavalo são inicializadas com seus valores explícitos

9. O construtor de Cavalo chega ao fim

Page 119: 57547801-Scjp

119

Construtores e instanciação

Pilha de chamadas aos construtores

Page 120: 57547801-Scjp

120

Construtores e instanciação

Regras para uso de construtores Construtores podem usar qualquer modificador de

visibilidade, incluindo private

Construtores não devem ter tipo de retorno

É permitido ter um método com o mesmo nome da classe, mas isso não o torna um construtor. Se há tipo de retorno, trata-se de um método e não um construtor

Se a classe não declarar um construtor, um construtordefault será automaticamente gerado pelo compilador

Page 121: 57547801-Scjp

121

Construtores e instanciação

Regras para uso de construtores (continuação)

O construtor default é sempre um construtor sem argumentos

Se queremos um construtor sem argumentos e foram declarados outros construtores (com argumentos) na classe, o compilador não fornecerá o construtor sem argumentos.

Todo construtor tem como sua primeira linha de código ou uma chamada a um construtor sobrecarregado (this()) ou uma chamada para o construtor da superclasse (super()), e essa última pode ser automaticamente inserida pelo compilador

Page 122: 57547801-Scjp

122

Construtores e instanciação

Regras para uso de construtores (continuação) Se a classe declara explicitamente um construtor, e não

for digitada a chamada a super() ou uma chamada parathis(), o compilador irá inserir uma chamada sem argumentos a super(), e essa será a primeira linha de código do construtor

Uma chamada para super() pode ser com ou sem argumentos

Não é permitido fazer uma chamada a um método de instância ou acessar uma variável de instância até que o construtor de super termine a sua execução

Page 123: 57547801-Scjp

123

Construtores e instanciação

Apenas variáveis e métodos estáticos podem ser acessados na chamada a super() ou a this(). (Ex: super(Animal.NOME) está OK, pois NOME é declarado como static)

As classes abstratas tem construtores, os quais são sempre chamados quando uma subclasse concreta é instanciada

Interfaces não têm construtores Não é permitido escrever código que chama um construtor.

Exemplo:class Cavalo {Cavalo() { } // construtor

void fazAlgo() {Cavalo(); // Chamada ilegal

}}

Page 124: 57547801-Scjp

124

Construtores e instanciação

Page 125: 57547801-Scjp

125

Construtores e instanciação

O que ocorre se o construtor da superclasse tiver argumentos?

Exemplo 1:class Animal {

Animal(String name) { }

}

class Cavalo extends Animal {

Horse() {

super(); // Erro de compilação!

}

}

Exemplo 2:class Animal {

Animal(String name) { }

}

class Cavalo extends Animal { } // Erro de compilação!

Page 126: 57547801-Scjp

126

Construtores e instanciação

Se a superclasse não define um construtor sem argumentos, duas coisas acontecem: A subclasse é obrigada a declarar um construtor e a

invocar super passando os argumentos necessários

A subclasse não pode usar o construtor defaultfornecido automaticamente pelo compilador, pois esse construtor somente faz uma chamada sem argumentos asuper

Page 127: 57547801-Scjp

127

Construtores e instanciação

Sobrecarga (overload) de construtores

Ocorre quando existem diferentes versões do construtor, cada uma delas tendo uma lista de argumentos distinta

Exemplo:class Foo {

Foo() { }

Foo(String s) { }

}

Page 128: 57547801-Scjp

128

O modificador static

Quando usar? Quando a execução do método não tem nenhuma dependência com o

estado das variáveis (atributos) dos objetos da classe. Ex: Classes com métodos utilitários

Quando todas as instâncias da classe precisam compartilhar o mesmo valor de um determinado atributo. Ex: Constantes (em conjunto com o modificador final)

Conceitos: Variáveis e métodos estáticos pertencem à classe ao invés de

pertencerem a qualquer instância específica

Há apenas uma cópia da variável estática na memória, ou seja, todas asinstâncias da classe “enxergam” o mesmo valor

Page 129: 57547801-Scjp

129

O modificador static

Exemplo 1:class Sapo {

static int contaSapo = 0; // Declara e inicializa a variável estáticapublic Sapo() {contaSapo += 1; // Altera o valor da variável}public static void main (String [] args) {new Sapo();new Sapo();new Sapo();System.out.println(“Contador igual a " + contaSapo);}

}

Saída do programa:Contador igual a 3

Page 130: 57547801-Scjp

130

O modificador static

Exemplo 2:class Sapo {

int contaSapo = 0; // Declara e inicializa a variável de instânciapublic Sapo() {contaSapo += 1; // Altera o valor da variável}public static void main (String [] args) {new Sapo();new Sapo();new Sapo();System.out.println(“Contador igual a " + contaSapo);}

}ERRO DE COMPILAÇÃO !!!!!

Page 131: 57547801-Scjp

131

O modificador static

Um método estático não pode acessar variáveis de instância (não-estáticas);

Pelo mesmo motivo, um método estático não pode invocar métodos de instância Variável ou método Estático = = Variável ou método

de Classe Variável ou método Não-estático = = Variável ou

método de Instância

Quando a JVM roda o método main, ela não cria nenhuma instância da classe

Page 132: 57547801-Scjp

132

O modificador static

Como acessar métodos e variáveis estáticas? Usar o ponto (.) após o nome da classe Exemplo:class Sapo {static int contaSapo = 0; // Declara e inicializa// a variável estáticapublic Sapo() {contaSapo += 1; // Altera o valor da variável} }class TestaSapo{

public static void main (String [] args) {new Sapo();new Sapo();new Sapo();System.out.println(“Contador igual a " + Sapo.contaSapo);}

}

Page 133: 57547801-Scjp

133

O modificador static

Métodos estáticos não podem ser sobrescritosclass Animal {

static void fazCoisas() {System.out.print("a ");}

}class Cao extends Animal {

static void fazCoisas() { // não é um overrideSystem.out.print("d ");}public static void main(String [] args) {Animal [] a = {new Animal(), new Cao(), new Animal()};for(int x = 0; x < a.length; x++)a[x].fazCoisas(); // invoca o método estático}

}

Saída do programa:a a a

Page 134: 57547801-Scjp

134

Coesão e Acoplamento

Coesão Determina se uma classe tem um propósito claro e

responsabilidades bem definidas

Classes altamente coesas são mais fáceis de manter e tendem a ser reutilizadas

Acoplamento Mede o quanto uma classe conhece dos detalhes de

implementação das outras classes

É desejável que as classes interajam entre si apenas através de suas API’s

O encapsulamento favorece o baixo acoplamento

Page 135: 57547801-Scjp

135

Objetivos

Utilizar os operadores da linguagem Java

Page 136: 57547801-Scjp

136

Operadores

Atribuição

Relacionais

Instanceof

Aritméticos

Concatenação de Strings

Incremento e Decremento

Operador condicional (Ternário)

Lógicos

Page 137: 57547801-Scjp

137

Operadores de Atribuição

São operadores de atribuição =, +=, -=, *= e /= Exemplo:y = y - 6;x = x + 2 * 5;

Produz o mesmo resultado que:y -= 6;x += 2 * 5; // a expressão do lado direito sempre é avaliada primeiro

Page 138: 57547801-Scjp

138

Operadores de Atribuição

O seguinte código compila sem problemas:boolean b = false;

if (b = true) { System.out.println("b is true");

} else { System.out.println("b is false"); }

Imprime b is true

O resultado de qualquer operação de atribuição é o valor que está sendo atribuído

O seguinte código NÃO compila:int x = 1;

if (x = 0) { } // x == 0 corrige o programa

Page 139: 57547801-Scjp

139

Operadores Relacionais

O resultado é sempre um valor booleano (true oufalse)

Há seis operadores: >, >=, <, <=, ==, e != == e != podem testar a igualdade de números, caracteres,booleanos e variáveis de referência

Quando os operandos são variáveis de referência, == retorna true somente se ambas as variáveis “apontam” para o mesmo objeto na memória

Page 140: 57547801-Scjp

140

Operadores de igualdade

Quando os operandos são variáveis de referênciaimport javax.swing.JButton;class CompareReference {

public static void main(String[] args) {JButton a = new JButton("Exit");JButton b = new JButton("Exit");JButton c = a;System.out.println("a == b? " + (a == b));System.out.println("a == c? " + (a == c));}

}

Saída do programa:a == b? falsea == c? true

Page 141: 57547801-Scjp

141

O operador instanceof

É usado para determinar se um determinado objeto passa no teste IS-A contra um tipo especificado

Somente pode ser usado para testar objetos contra tipos da sua mesma hierarquia

Para interfaces, um objeto passa no teste deinstanceof se qualquer superclasse implementar a interface especificada

Page 142: 57547801-Scjp

142

O operador instanceof

Exemploclass A { }class B extends A {

public static void main (String [] args) {A myA = new B();m2(myA);}public static void m2(A a) {if (a instanceof B)((B)a).doBstuff(); // downcasting}public static void doBstuff() {System.out.println("'a' refers to a B");}

}

Page 143: 57547801-Scjp

143

Operadores Aritméticos

Quatro operadores básicos: soma (+), subtração (-), multiplicação (*) e divisão (/)

O operador % retorna o resto da divisão

As expressões são avaliadas da esquerda para a direita, a não ser que haja parênteses, ou a não ser que alguns operadores tenham maior precedência

Os operadores *, /, e % têm maior precedência que + e -

Page 144: 57547801-Scjp

144

Concatenação de Strings

Realizada pelo operador +

Se qualquer operando for uma String, o operador + fará a concatenação dos operandos

Se ambos os operandos forem numéricos, o operador + fará a soma aritmética dos operandos

Page 145: 57547801-Scjp

145

Concatenação de Strings

Exemplo 1String animal = “Cavalo " + “branco";

Exemplo 2String a = "String";int b = 3;int c = 7;System.out.println(a + b + c); // imprime String37

Exemplo 3String a = "String";int b = 3;int c = 7;System.out.println(a + (b + c)); // imprime

String10

Page 146: 57547801-Scjp

146

Incremento de Decremento

São realizados com os operadores ++ e --

O pré-incremento ou pré-decremento ocorre antes do valor ser utilizado na expressão

O pós-incremento ou pós-decremento ocorre depois que o valor é utilizado na expressão

Page 147: 57547801-Scjp

147

Incremento de Decremento

Exemploclass MathTest {

static int players = 0;public static void main (String [] args) {System.out.println("players online: " + players++);System.out.println("The value of players is "+ players);System.out.println("The value of players is now "+ ++players);}

}

Saída do programa:players online: 0The value of players is 1The value of players is now 2

Page 148: 57547801-Scjp

148

Operador ternário

Possui três operandos:x = (expressao booleana) ? Valor1 : Valor2

Retorna um dos dois valores especificados dependendo da expressão booleana Se a expressão for true, retorna o valor depois de ?

Se a expressão for false, retorna o valor depois de :

Page 149: 57547801-Scjp

149

Operadores lógicos

O exame cobra seis operadores: &, |, ^, !, && e || Operadores lógicos trabalham com duas

expressões booleanas (exceto !) Os operadores && e & retornam true se os dois

operandos são true Os operadores || e | retornam true se qualquer

operando é true && não avalia o operando da direita caso o

operando da esquerda seja false

Page 150: 57547801-Scjp

150

Operadores lógicos

|| não avalia o operando da direita se o da esquerda é true

Os operadores & e | sempre avaliam os doisoperandos

O operador ^ (ou-exclusivo) retorna true se exatamente um operando é true

O operador ! (negação) retorna o valor oposto ao valor do seu operando booleano

Page 151: 57547801-Scjp

151

Operadores lógicos

Exemplo 1int z = 5;

if(++z > 5 || ++z > 6) z++; // z = 7 depois dessa linha

Exemplo 2int z = 5;

if(++z > 5 | ++z > 6) z++; // z = 8 depois dessa linha

Page 152: 57547801-Scjp

152

Objetivos

Utilizar os comandos if e switch

Implementar loops com os comandos for, while edowhile, e utilizar break e continue

Utilizar try, catch e finally

Reconhecer os efeitos das exceções

Reconhecer exceções comuns

Implementar código com o comando assert

Page 153: 57547801-Scjp

153

O comando if-else

Sintaxe básica:if (expressaoBooleana) {System.out.println(“Entrei no if”);}

Exemplosif (x > 3) {

ystem.out.println(“x maior que 3”);} else {

System.out.println(“x nao e’ maior que 3”);}if (x > 3) {

y = 2;} // else opcionalz += 8;a = y + x;

Page 154: 57547801-Scjp

154

O comando if-else

Chaves são opcionais para blocos que contenham apenas uma expressão O seguinte código:if (x > 3) {

y = 2;}z += 8;a = y + x;

É equivalente a:if (x > 3) // nao adere as convencoes da Sun

y = 2;z += 8;a = y + x;

Cuidado com a indentação!if (x > 3)

y = 2;z += 8;a = y + x;

Page 155: 57547801-Scjp

155

O comando if-else

If-else aninhadosif (price < 300) {

buyProduct();} else {

if (price < 400) {getApproval();

}else {

dontBuyProduct();}

}// Equivalente ao anteriorif (price < 300) {

buyProduct();} else if (price < 400) {

getApproval();} else {

dontBuyProduct();}

Page 156: 57547801-Scjp

156

O comando if-else

Cuidado com a indentação!// Exemplo 1int x = 1;if ( x == 3 ) { }else if (x < 4) {System.out.println("<4"); }else if (x < 2) {System.out.println("<2"); }else { System.out.println("else"); }// Exemplo 2if (exam.done())if (exam.getScore() < 0.61)System.out.println("Try again.");else System.out.println("Java master!");// Exemplo 3if (exam.done())

if (exam.getScore() < 0.61)System.out.println("Try again.");

elseSystem.out.println("Java master!");

Page 157: 57547801-Scjp

157

O comando if-else

O comando if trabalha com expressões booleanasint y = 5;int x = 2;if ((x > 3) && (y < 2) | doStuff()) {System.out.println("true");}

Somente são aceitas expressões booleanasint trueInt = 1;int falseInt = 0;if (trueInt) // ilegalif (trueInt == true) // ilegalif (1) // ilegalif (falseInt == false) // ilegalif (trueInt == 1) // okif (falseInt == 0) // ok

Page 158: 57547801-Scjp

158

O comando if-else

Cuidado com atribuições que podem ser confundidas com testes de igualdade:

boolean x = false;

if (x = true) { } // atribuicao, x sempre sera true

int x = 3;

if (x = 5) { } // Nao compila!

Page 159: 57547801-Scjp

159

O comando switch

Sintaxe básicaswitch (expressao) {

case constante1: bloco de codigo

case constante2: bloco de codigo

default: bloco de codigo

}

Page 160: 57547801-Scjp

160

O comando switch

Exemplo 1int x = 3;switch (x) {

case 1:System.out.println(“x igual a 1”);break;

case 2:System.out.println(“x igual a 2”);break;

case 3:System.out.println(“x igual a 3”);break;

default:System.out.println(“nao conheco x”);

}

Page 161: 57547801-Scjp

161

O comando switch

Exemplo 2enum Color {red, green, blue}

class SwitchEnum {

public static void main(String [] args) {

Color c = Color.green;

switch(c) {

case red: System.out.print("red ");

case green: System.out.print("green ");

case blue: System.out.print("blue ");

default: System.out.println("done");

}

}

}

Page 162: 57547801-Scjp

162

O comando switch

A expressão de um switch somente aceita enum, byte, short, int, e char. Não é permitido fazerlong s = 30;

switch(s) {

case 12: // codigo aqui

case 3: // mais codigo aqui

}

Page 163: 57547801-Scjp

163

O comando switch

O case deve testar um valor constante, que deve ser um literal, variável final, ou então uma expressão constante, incluindo um enum.final int a = 1;

final int b;

b = 2;

int x = 0;

switch (x) {

case a: // ok

case b: // erro de compilacao!

}

Page 164: 57547801-Scjp

164

O comando switch

Não é permitido ter dois cases que testam o mesmo valor

int temp = 90;switch(temp) {

case 80 : System.out.println("80");case 80 : System.out.println("80"); // Nao compila!case 90 : System.out.println("90");default : System.out.println("default");

}

É permitido utilizar autoboxingswitch(new Integer(4)) {

case 4: System.out.println("boxing is OK");}

Page 165: 57547801-Scjp

165

O comando switch

Se a condição no comando switch casa com algum case, a execução irá percorrer todo o código desde o case encontrado, até que um comando break ou o final doswitch sejam alcançados.

A palavra-chave default deve ser usada quando é preciso executar código quando nenhum dos cases casa com o valor condicional. Nesse caso, o bloco default será executado, e se não contiver um break, o código continuará a executar até o final do switch ou até que umbreak seja encontrado

Page 166: 57547801-Scjp

166

Os comandos while e do-while

Whileint x = 2;

while(x == 2) {

System.out.println(x);

++x;

}

Do-Whiledo {

System.out.println("Inside loop"); // executado 1 vez

} while(false);

Page 167: 57547801-Scjp

167

Os comandos while e do-while

Declarações válidas e inválidas

int x = 1;

while (x) { } // Nao compila; x deve ser booleano

while (x = 5) { } // Nao compila; resulta no valor 5

while (x == 5) { } // Ok, teste de igualdade, resultado booleano

while (true) { } // Ok

Page 168: 57547801-Scjp

168

O comando for básico

Sintaxefor (/*Inicialização*/ ; /*Condição*/ ; /* Iteração

*/) {

/* corpo do loop */

}

Exemplosfor (int i = 0; i<10; i++) {

System.out.println("i = " + i);

}

for (int x = 10, y = 3; y > 3; y++) { }

Page 169: 57547801-Scjp

169

O comando for básico

Se uma variável é incrementada ou avaliada dentro do for, ela deve ser declarada antes do loop ou na declaração do for

Uma variável declarada na declaração do for ou criada dentro do bloco definido pelo for não pode ser acessada de fora do for

Exemplo:for (int x = 1; x < 2; x++) {

System.out.println(x); // Ok}System.out.println(x); // Nao compila! x esta fora do

escopo

Page 170: 57547801-Scjp

170

O comando for básico

Declarações válidasfor (;;) { // nenhuma das tres partes e’ obrigatoria

System.out.println("loop infinito");

}

int i = 0;

for (; i < 10;) { // somente a expressao condicional; funciona como while

i++;

// mais codigo aqui

}

for (int i = 0, j = 0; (i < 10) && (j < 10); i++, j++) {

System.out.println("i = " + i + " j = " + j);

}

int b = 3;

for (int a = 1; b != 1; System.out.println("iterate")) {

b = b - a;

}

Page 171: 57547801-Scjp

171

O comando for aprimorado

Sintaxefor(declaracao : expressao)

A expressão é o array ou coleção a qual se deseja percorrer

A declaração é a variável (escopo de bloco), cujo tipo é compatível com os elementos do array ou coleção. A variável contém o valor do elemento de uma dada iteração

Page 172: 57547801-Scjp

172

O comando for aprimorado

O novo for: “for-each”, “enhanced for”, “for-in”

Simplifica a iteração sobre arrays e coleções

Exemplosint[] a = { 1, 2, 3, 4 };

for (int x = 0; x < a.length; x++)

// for basico

System.out.print(a[x]);

for (int n : a)

// novo for

System.out.print(n);

Page 173: 57547801-Scjp

173

O comando for aprimorado

Declarações válidas e inválidasint x;long x2;Long [] La = {4L, 5L, 6L};long [] la = {7L, 8L, 9L};int [][] twoDee = {{1,2,3}, {4,5,6}, {7,8,9}};String [] sNums = {"one", "two", "three"};Animal [] animals = {new Dog(), new Cat()};// declaracoes validasfor(long y : la ) ;for(long lp : La) ;for(int[] n : twoDee) ;for(int n2 : twoDee[2]) ;for(String s : sNums) ;for(Object o : sNums) ;for(Animal a : animals) ;// declaracoes invalidasfor(x2 : la) ; // x2 ja foi declaradafor(int x2 : twoDee) ; // tipos incompativeis: array e intfor(int x3 : la) ; // tipos incompativeis: long e intfor(Dog d : animals) ; // nem todo animal e’ um cao

Page 174: 57547801-Scjp

174

O uso do break e continue

Exemplos sem labelfor (int i = 0; i < 10; i++) {

System.out.println(“entrei no loop");if (foo.doStuff() == 5) {continue;

}// mais codigo, que nao sera executado quando o if acima// for verdadeiro}boolean problem = true;while (true) {

if (problem) {System.out.println(“Houve um problema");break;}

}// mais codigo

Page 175: 57547801-Scjp

175

O uso do break e continue

Exemplos com label// Ex 1

boolean isTrue = true;

outer: // -> identificador valido

for(int i=0; i<5; i++) {

while (isTrue) {

System.out.println("Hello");

break outer;

}

System.out.println("Outer loop.");

}

System.out.println("Good-Bye");

// Ex 2outer:for (int i=0; i<5; i++) {

for (int j=0; j<5; j++) {System.out.println("Hello");continue outer;} // end of inner loop

System.out.println("outer");}System.out.println("Good-Bye");

Page 176: 57547801-Scjp

176

O uso do break e continue

Um break provocará a interrupção da iteração atual doloop mais interno e a linha de código seguinte ao loopserá executada

Um continue provocará a interrupção da iteração atual do loop mais interno, a execução da expressão da iteração e a avaliação da condição daquele loop, e, caso a condição seja true, o loop será novamente executado

Caso break ou continue sejam usados com label, provocarão efeito similar no loop marcado com o label, e não no loop mais interno

Page 177: 57547801-Scjp

177

Tratamento de exceções

Exceção == condição ou situação excepcional

Uma exceção pode ser causada por vários motivos: falha de hardware, falta de recursos da máquina, bugs…

Quando um evento que gera exceção ocorre em Java, dizemos que a exceção é lançada (throw)

O código responsável por tratar a exceção pega a exceção (catch)

Page 178: 57547801-Scjp

178

Tratamento de exceções

Sintaxetry {

// 1a linha de codigo da “regiao protegida”// Codigo aqui pode causar algum tipo de excecao

}catch(MyFirstException) {

// Codigo que trata essa excecao especifica}catch(MySecondException) {

// Codigo que trata essa excecao}

// Restante do codigo, nao protegido

Page 179: 57547801-Scjp

179

Tratamento de exceções

Uso do bloco finallytry {// codigo protegido}catch(MyFirstException) {// Codigo que trata essa excecao}catch(MySecondException) {// Codigo que trata essa excecao}finally {// Codigo de fechamento, limpeza e liberacao de recursos// eventualmente alocados no try}// mais codigo

Page 180: 57547801-Scjp

180

Tratamento de exceções

O bloco finally (opcional) sempre será invocado, independente se uma exceção foi ou não lançada no try ou se foi ou não tratada no catch

O único caso de exceção à regra “finally sempre é executado” é que um finally não será executado caso a JVM seja desligada. Isto pode ocorrer se código dos blocos try/catch chamarem System.exit()

O fato de finally ser sempre executado não significa que será sempre inteiramente executado. Código no blocofinally pode lançar uma exceção ou executar um System.exit()

Page 181: 57547801-Scjp

181

Tratamento de exceções

Declarações válidas e inválidas// Ex 1: Oktry {

// codigo protegido} finally {

//libera recursos}// Ex 2: Errotry {

// codigo protegido}

// precisa de um catch ou finallySystem.out.println(“hello");

// Ex 3: Errotry {

// codigo protegido}

// nao pode existir codigo entre try/catchSystem.out.println(“sai do try");

catch(Exception ex) { }

Page 182: 57547801-Scjp

182

Tratamento de exceções

Propagação de exceções Exceções não tratadas (apenas lançadas) se propagam

através da pilha de chamadas, iniciando pelo método que originou a exceção e terminando ou com o primeiro método que tem um catch adequado para aquela exceção ou com a parada da JVM (que ocorre se a exceção chega a main(), e main() apenas a declara)

Page 183: 57547801-Scjp

183

Tratamento de exceções

Uma exceção é um objeto da classe Exception

Page 184: 57547801-Scjp

184

Tratamento de exceções

Tratando uma hierarquia de exceçõesimport java.io.*;public class ReadData {

public static void main(String args[]) {try {

RandomAccessFile raf = new RandomAccessFile("myfile.txt", "r");byte b[] = new byte[1000];raf.readFully(b, 0, 1000);

} catch (FileNotFoundException e) {System.err.println("File not found");System.err.println(e.getMessage());e.printStackTrace();

} catch (IOException e) {System.err.println("IO Error");System.err.println(e.toString());e.printStackTrace();

}}

}

Page 185: 57547801-Scjp

185

Tratamento de exceções

Tratando uma hierarquia de exceções Todos os blocos catch devem estar ordenados do mais

específico para o mais geral. Se há um catch paraIOException e outro para Exception, o catch deIOException deve vir primeiro no código. Caso contrário, a IOException seria tratada pelo catch(Exception e), pois um catch pode tratar a exceção especificada ou qualquer um de seus subtipos.

Page 186: 57547801-Scjp

186

Tratamento de exceções

As exceções dividem-se em checked e unchecked Unchecked são as exceções que herdam de

RuntimeException

Checked são as exceções que herdam da classeException, e que não estendem RuntimeException

Page 187: 57547801-Scjp

187

Tratamento de exceções

As checked exceptions estão sujeitas à regra “declare ou trate”. Qualquer método que possa lançar uma checked exception (incluindo métodos que invocam métodos que podem lançar umachecked exception) devem ou declarar a exceção usando throws ou então tratar a exceção com um bloco try/catch

Subtipos de Error ou RuntimeException são ditosunchecked, de forma que o compilador não obriga a regra “declare ou trate”.

Page 188: 57547801-Scjp

188

Tratamento de exceções

É possível criar exceções customizadasestendendo a classe Exception

A exceção será considerada como checked exception, e o compilador irá obrigar o cumprimento da regra “declare ou trate”

Exemploclass MyException extends Exception { }

Page 189: 57547801-Scjp

189

Tratamento de exceções

Page 190: 57547801-Scjp

190

assert

Mecanismo fornecido pela linguagem a partir da versão 1.4

O uso de asserts permite que as proposições assumidas no código sejam testadas em tempo de desenvolvimento e depuração O objetivo de um assert é testar se uma condição é sempre

verdadeira

Asserts são habilitados durante a fase de testes e desabilitados durante produção

O exame cobra conhecer como o mecanismo de assertfunciona, como habilitá-lo e quando usar e não usar asserts

Page 191: 57547801-Scjp

191

assert

Exemploprivate void methodA(int num) {

assert (num>=0); // lança um AssertionError

// se o teste nao for true

useNum(num + x);

}

O assert permanece inativo a não ser que esteja ativado

O código em produção (assert desabilitado) executaria como se tivesse sido escrito assim:

private void methodA(int num) {

useNum(num + x);

}

Page 192: 57547801-Scjp

192

assert

Sintaxe – Forma 1private void doStuff(){

assert (y > x);

// codigo que assume que y e’ maior que x

}

Sintaxe – Forma 2private void doStuff() {

assert (y > x): "y = " + y + " x = " + x;

// codigo que assume que y e’ maior que x

}

Page 193: 57547801-Scjp

193

assert

Declarações válidas e inválidasvoid noReturn() { }int aReturn() { return 1; }void go() {

int x = 1;boolean b = true;assert(x == 1); // okassert(b); // okassert true; // okassert(x == 1) : x; // okassert(x == 1) : aReturn(); // okassert(x == 1) : new ValidAssert(); // okassert(x = 1); // nao compilaassert(x); // nao compilaassert 0; // nao compilaassert(x == 1) : ; // nao compilaassert(x == 1) : noReturn(); // nao compilaassert(x == 1) : ValidAssert va; // nao compila

}

Page 194: 57547801-Scjp

194

assert

assert vem por padrão desabilitado em tempo de execução

Para habilitar a execução com assert, utilizar aflag -ea ou – enableassertions

Exemplos:java -ea com.ks.TestClass

java -enableassertions com.ks.TestClass

Page 195: 57547801-Scjp

195

assert

Para desabilitar o uso de asserts, utilizar a flag -daor –disableassertions

A desabilitação é o mesmo que executar a classe sem usar a flag –ea

Útil para habilitar o assert em algumas classes do sistema e desabilitar em outras

Exemplos:java -da com.ks.TestClass

java -disableassertions com.ks.TestClass

Page 196: 57547801-Scjp

196

assert

É possível combinar as flags para ter asserthabilitado para algumas classes e desabilitado para outras, ou o contrário

Exemplo:

java -ea -da:MyClass TestClass

Se a habilitação ou desabilitação for feita utilizando as flags sem argumentos, o efeito será global

Page 197: 57547801-Scjp

197

assert

Quando usar asserts Não utilizar asserts para validar argumentos de

métodos públicos

Não utilizar asserts que causem efeitos colaterais.

Utilizar asserts – mesmo em métodos públicos – para validar que um bloco de código em particular nunca será alcançado. É possível usar assert false; para código que nunca deve ser executado, de forma que umassertion error é lançado imediatamente se o comandoassert for executado

Page 198: 57547801-Scjp

198

assert

Exemplospublic void doStuff(int x) {

assert (x > 0); // uso inadequado// codigo que usa x

}private void doMore(int x) { // uso apropriado

assert (x > 0);// codigo que usa x

}switch(x) { // uso apropriado

case 1: y = 3;case 2: y = 9;case 3: y = 27;default: assert false; // essa situacao nunca deveria ocorrer!

}

Page 199: 57547801-Scjp

199

Objetivos

Utilizar atributos de classe e entender a inicialização devariáveis de instância

Entender o escopo e a inicialização de variáveis locais

Utilizar primitivos e arrays

Desenvolver código que utiliza Wrappers e Autoboxing

Determinar os efeitos da passagem de parâmetros para métodos

Reconhecer quando objetos tornam-se elegíveis para garbage collection

Page 200: 57547801-Scjp

200

Mapa da memória – Stack e Heap

Como os elementos são armazenados na memória da máquina virtual Java

Objetos e Variáveis de instância vivem na heap

Variáveis locais vivem na stack

Entender esse funcionamento é útil para resolver diversas questões do exame

Page 201: 57547801-Scjp

201

Mapa da memória – Stack e Heap

Como os elementos são armazenados na memória da máquina virtual Java Objetos e Variáveis de instância vivem na heap

Variáveis locais vivem na stack

Entender esse funcionamento é útil para resolver diversas questões do exame

Page 202: 57547801-Scjp

202

Mapa da memória – Stack e Heap

class Collar { }

class Dog {

Collar c; // variável de instância

String name; // variável de instância

public static void main(String [] args) {

Dog d; // variável local: d

d = new Dog();

d.go(d);}

void go(Dog dog) { // variável local: dog

c = new Collar();

dog.setName(“Aiko");}

void setName(String dogName) { // variável local: dogName

name = dogName;}

}

Page 203: 57547801-Scjp

203

Mapa da memória – Stack e Heap

Page 204: 57547801-Scjp

204

Literais

Números inteiros podem ser representados da seguinte forma em Java: Decimais – int tamanho = 343;

Octais – int num = 011; (colocar um zero na frente do número)

Hexadecimais – int x = 0x7fffff; (equivalente a 0X7ffFfF)

Todo literal inteiro é um int por padrão (32 bits)! long n = 110600L (equivalente a 110600l)

Page 205: 57547801-Scjp

205

Literais

Números de ponto flutuante são definidos como um número, um símbolo decimal (sempre um ponto (.)) e mais números:double d = 11301874.9881024;

Todo literal de ponto flutuante é um double por padrão (64 bits)!float f = 23.467890; // Erro de compilação:possible loss of precision

float g = 49837849.029847F; // OK, tem o sufixo "F“ (ou “f”)

Page 206: 57547801-Scjp

206

Literais

Booleanostrue e falseboolean t = true; // Legalboolean f = 0; // Erro de compilação

Caractereschar a = 'a';char b = '@';

São na verdade inteiros de 16 bits sem sinal (armazenam de 0 a 65535)

StringsString s = “Curso SCJP”;

Page 207: 57547801-Scjp

207

Cast de tipos primitivos

class Casting {public static void main(String [] args) {

int x = 3957.229; // Erro de compilação}

}

Corrigindo:class Casting {

public static void main(String [] args) {int x = (int)3957.229; // operação válida

System.out.println("int x = " + x); // imprimeint x = 3957

}}

Page 208: 57547801-Scjp

208

Atribuição de tipos primitivos

Exemplo:class ValueTest {

public static void main (String [] args) {

int a = 10; // Atribui um valor a a

System.out.println("a = " + a);

int b = a;

b = 30;

System.out.println("a = " + a + " apos alteracao em b");

}

Page 209: 57547801-Scjp

209

Atribuição de variáveis de referência

Exemplo:Button b = new Button();

A linha de código acima faz três operações:

Cria uma nova variável de referência chamada b, do tipo Button

Cria um novo objeto Button na heap e atribui o objeto recém criado à variável de referência b

Page 210: 57547801-Scjp

210

Atribuição de variáveis de referência

Exemplo:Button b = null;

A linha de código acima faz três operações:

Cria uma nova variável de referência chamada b, do tipo Button

Faz com que a variável b não “aponte” para nenhum objeto

Page 211: 57547801-Scjp

211

Atribuição de variáveis de referência

Exemploimport java.awt.Dimension;class ReferenceTest {

public static void main (String [] args) {Dimension a = new Dimension(5,10);System.out.println("a.height = " + a.height);Dimension b = a;b.height = 30;System.out.println("a.height = " + a.height +" apos mudanca de b");

}}

Saída do programaa.height = 10a.height = 30 apos mudanca de b

Page 212: 57547801-Scjp

212

Escopo de variáveis

Como é o ciclo de vida das variáveis em Java?class Layout {

static int s = 343; // variável estática

int x; // variável de instância

{ x = 7; int x2 = 5; } // bloco de inicialização

Layout() { x += 8; int x3 = 6;} // construtor

void doStuff() {

int y = 0; // variável local

for(int z = 0; z < 4; z++) { // bloco de iteração

y += z + x;

}

}

}

Page 213: 57547801-Scjp

213

Escopo de variáveis

Regras básicas: Variáveis estáticas possuem o escopo mais duradouro;

Variáveis de instância são criadas quando uma nova instância é criada, e sobrevivem até que a instância seja coletada pelo garbage collector

Variáveis locais sobrevivem apenas no contexto do método em que são declaradas

Variáveis de bloco sobrevivem apenas enquanto o bloco está executando

Page 214: 57547801-Scjp

214

Escopo de variáveis

Exemplo:class ScopeErrors {

public static void main(String [] args) {ScopeErrors s = new ScopeErrors();s.go();}void go() {int y = 5;go2();y++; // assim que go2() terminar, y volta a estar no escopo}void go2() {y++; // erro de compilação: cannot find symbol}

}

Page 215: 57547801-Scjp

215

Inicialização de variáveis de instância

O programador tem a opção de deixar a variável não-inicializada

Neste caso, a variável assume um valor padrão quando uma nova instância é criada

Page 216: 57547801-Scjp

216

Inicialização de variáveis de instância

Variáveis de instância como tipos primitivospublic class Data {

int ano; // Variável de instância primitivapublic static void main(String [] args) {Data d = new Data();d.mostraAno();}public void mostraAno() {System.out.println(“O ano é " + ano);}

}

Saída do programa:O ano é 0

Page 217: 57547801-Scjp

217

Inicialização de variáveis de instância

Variáveis de instância como referências para objetospublic class Livro {

private String titulo; // Variável de instância de referência

public String getTitulo() {

return titulo;

}

public static void main(String [] args) {

Livro b = new Livro();

System.out.println"O titulo é “ + b.getTitulo());

}

}

Saída do programa:

O titulo é null

Page 218: 57547801-Scjp

218

Inicialização de variáveis de instância

Variáveis de instância como arrayspublic class Calendario {static int [] ano = new int[100]; // se int[] ano; ano

seria nullpublic static void main(String [] args) {for(int i=0;i<100;i++)System.out.println("ano[" + i + "] = " + ano[i]);}

}

Saída do programa:ano[0] = 0ano[1] = 0 ...ano[98] = 0ano[99] = 0

Page 219: 57547801-Scjp

219

Inicialização de variáveis de instância

Se a variável array está inicializada, os seus elementos estão também inicializados, com os mesmos valores padrão que receberiam caso fossem variáveis de instância

Os elementos de um array são sempre inicializados com valores padrão, independente do tipo de variável do array

Page 220: 57547801-Scjp

220

Inicialização de variáveis locais

O programador é obrigado a inicializar a variável local Se a variável não for inicializada, ocorrerá erro de

compilação na primeira tentativa de uso da variável

Page 221: 57547801-Scjp

221

Inicialização de variáveis locais

Variáveis locais como tipos primitivos Exemplo 1: Erro de compilaçãopublic class TimeTravel {public static void main(String [] args) {int ano; // variavel local (declarada mas nao inicializada)System.out.println("O ano é " + ano); // ERRO! Variable may not have// been initialized}}

Exemplo 2: Compila OKpublic class TimeTravel {public static void main(String [] args) {int ano; // declarada mas nao inicializadaint dia; // declarada mas nao inicializadaSystem.out.println("Entre no portal");ano = 2050; // Atribui um valorSystem.out.println("Bem vindo ao ano " + ano);}}

Page 222: 57547801-Scjp

222

Inicialização de variáveis locais

Variáveis locais como variáveis de referênciaimport java.util.Date;

public class TimeTravel {

public static void main(String [] args) {

Date date;

if (date == null) // Erro de compilação!

System.out.println("date is null");

}

}

Variáveis de referência locais nunca sãoinicializadas com o valor padrão null A linha Date date = null; resolve o erro

Page 223: 57547801-Scjp

223

Passagem de parâmetros - Objetos

Quando passamos um objeto como parâmetro para um método, estamos na realidade passando uma referência para o objeto e não o objeto em si

IMPORTANTE: Quando a variável de referência é passada para o método, o método recebe uma cópia da variável

Tanto o método chamado quanto o códigochamador terão cópias idênticas da referência para o objeto, “apontando” para o mesmo objeto na memória

Page 224: 57547801-Scjp

224

Passagem de parâmetros - Objetos

import java.awt.Dimension;

class ReferenceTest {

public static void main (String [] args) {

Dimension d = new Dimension(5,10);

ReferenceTest rt = new ReferenceTest();

System.out.println(“Antes de altera() d.height = "

+ d.height);

rt.altera(d);

System.out.println(“Apos altera() d.height = "

+ d.height);

}

void altera(Dimension dim) {

dim.height = dim.height + 1;

System.out.println("dim = " + dim.height);

}

}

Saída do programa:Antes de altera()

d.height = 10dim = 11

Apos altera() d.height = 11

Page 225: 57547801-Scjp

225

Passagem de parâmetros - Objetos

A passagem é por valor!

Uma cópia da referência é passada como parâmetro para o método

Como o chamador e o método chamado ambos possuem cópias idênticas da variável, qualquer mudança feita no objeto será visível no contexto do chamador.

Page 226: 57547801-Scjp

226

Passagem de parâmetros - Objetos

ATENÇÃO: O método chamado não é capaz de alterar o valor da variável

original (do código chamador) Exemplo:

void bar() {Foo f = new Foo();doStuff(f);}void doStuff(Foo g) {g.setName("Boo");g = new Foo();}

Fazer a variável g apontar para um novo objeto, não faz f apontar para um novo objeto!

Page 227: 57547801-Scjp

227

Passagem de parâmetros - Primitivos

class ReferenceTest {public static void main (String [] args) {

int a = 1;ReferenceTest rt = new ReferenceTest();System.out.println(“Antes de altera() a = " + a);rt.altera(a);System.out.println("Apos altera() a = " + a);

}void altera(int number) {

number = number + 1;System.out.println("number = " + number);

}}

Saída do programa:Antes de altera() a = 1number = 2Apos altera() a = 1

Page 228: 57547801-Scjp

228

Arrays

Conceitos Declaração

Construção

Inicialização

Page 229: 57547801-Scjp

229

Arrays

Conceitos Um array é um objeto em Java que armazena múltiplas

variáveis de um mesmo tipo

Todo array é um objeto. Mesmo um array de primitivos é um objeto na memória

Page 230: 57547801-Scjp

230

Arrays

Instanciando um array Instanciar um array significa criar um novo objeto

array na memória

O tamanho do array (número de elementos) deve ser especificado neste momento

Exemplo:int[] teste; // Declara um array de ints

teste = new int[4]; // Constroi o array e

// atribui a variavel teste

Page 231: 57547801-Scjp

231

Arrays

Efeitos da instanciação de arrays Quantos objetos são criados na memória depois que as

linhas de código a seguir executarem?int[] teste = new int[10];

Thread[] threads = new Thread[5];

Page 232: 57547801-Scjp

232

Arrays

Arrays multidimensionaisint[][] myArray = new int[3][]; // declara econstroi um array de 2 dimensoes do tipoint

myArray[0] = new int[2];

myArray[0][0] = 6;

myArray[0][1] = 7;

myArray[1] = new int[3];

myArray[1][0] = 9;

myArray[1][1] = 8;

myArray[1][2] = 5;

Page 233: 57547801-Scjp

233

Arrays

Arrays multidimensionais

Page 234: 57547801-Scjp

234

Arrays

Inicialização Inicializar o array significa atribuir valor aos seus elementos Array de primitivos: preencher cada elemento primitivo com o

valor adequadoint[] x = new int[5];x[4] = 2; // OKx[5] = 3; // Runtime exception: Não existe índice 5// (ArrayIndexOutOfBoundsException)Array de objetos: atribuir a cada elemento uma referência para um objeto

do tipo (ou subtipo) do arrayAnimal [] pets = new Animal[3];pets[0] = new Animal();pets[1] = new Animal();pets[2] = new Animal();

Page 235: 57547801-Scjp

235

Arrays

Inicializando o array em um loopCao[] meusCaes = new Cao[6];

for (int x = 0; x < meusCaes.length; x++) {

meusCaes[x] = new Cao(); // atribui um novoCao a posicao com indice x

}

Page 236: 57547801-Scjp

236

Arrays

Construindo e Inicializando em um único comando (tipo 1)Dog puppy = new Dog("Frodo");

Dog[] myDogs = {puppy, new Dog("Clover"), new Dog("Aiko")};

Page 237: 57547801-Scjp

237

Arrays

Construindo e Inicializando em um único comando (tipo 2) Array anônimoint[] teste;teste = new int[] {4,7,2}; // nunca especificar o tamanho!

Exemplo de uso: Passar um array para um métodopublic class MeuTeste {

void recebeUmArray(int [] umArray) {// use o parametro array}

public static void main (String [] args) {MeuTeste o = new MeuTeste();o.recebeUmArray(new int[] {7,7,8,2,5}); // cria um array// e passa como parametro}}

Page 238: 57547801-Scjp

238

Arrays

Atribuindo valores aos elementos do array Array de primitivosint[] lista = new int[5];

byte b = 4;

char c = 'c';

short s = 7;

lista[0] = b; // OK, byte eh menor que int

lista[1] = c; // OK, char eh menor que int

lista[2] = s; // OK, short eh menor que int

Page 239: 57547801-Scjp

239

Arrays

Atribuindo valores aos elementos do array Array de objetos: é permitido armazenar objetos de

qualquer subclasse da classe declarada do arrayclass Car {}class Subaru extends Car {}class Ferrari extends Car {}...Car [] myCars = {new Subaru(), new Car(), new

Ferrari()};

Qualquer objeto que passe no teste “IS-A” executado com a classe declarada do array pode ser atribuído a um elemento do array

Page 240: 57547801-Scjp

240

Arrays

Atribuindo valores a variáveis de referência paraarrays Array de primitivosint[] s;

int[] d = new int[4];

char[] lex = new char[5];

s = d; // OK, d aponta para um array de ints

s = lex; // Erro de compilacao, lex aponta para um arrayde char

Page 241: 57547801-Scjp

241

Arrays

Atribuindo valores a variáveis de referência paraarrays Array de objetosCar[] carros;

Honda[] carrosImportados = new Honda[5];

carros = carrosImportados; // OK, Honda “IS-A” Car

Bebida[] bebidas = new Bebida[99];

carros = bebidas; // Erro de compilacao!

Page 242: 57547801-Scjp

242

Blocos de inicialização

O código de uma classe pode estar em: Métodos Construtores Blocos de inicialização

Os blocos de inicialização são executados quando a classe é carregada pela primeira vez (blocos estáticos) ou então quando uma nova instância da classe é criada

A ordem em que os blocos aparecem no código da classe influencia no resultado

Page 243: 57547801-Scjp

243

Wrappers

Servem basicamente a dois propósitos: Permitir que tipos primitivos possam ser incluídos em

operações exclusivas de objetos, como ser adicionado a uma coleção ou ser retornado de um método queretorna um objeto

Fornecer uma gama de funções utilitárias para os tipos primitivos

Page 244: 57547801-Scjp

244

Wrappers

Page 245: 57547801-Scjp

245

Wrappers

Como criar um objeto WrapperTrês formas são cobradas no exame:Integer i1 = new Integer(42);//recebe um int (primitivo

associado)

Integer i2 = new Integer("42");//recebe uma representacao do primitivo em forma de String

Integer i3 = new Integer(“tres"); // Runtime Exception:

// NumberFormatException

Integer i2 = Integer.valueOf("101011", 2); // converte 101011

// para 43 e atribui o valor 43 ao objeto Integer

Float f1 = new Float(3.14f); // recebe um float (primitivo associado)

Float f2 = new Float("3.14f");

Float f2 = Float.valueOf("3.14f");

Page 246: 57547801-Scjp

246

Wrappers

Principais métodos xxxValue() – obtém o valor do primitivo armazenado dentro do

objeto WrapperInteger i2 = new Integer(42);

int iPrimitivo = i2.intValue();

parseXxx() – retorna um primitivo a partir de uma String que o representadouble d4 = Double.parseDouble("3.14");

toXxxString() – permite converter um número na base 10 para uma String contendo a sua representação hexa, binária ou octalString s3 = Integer.toHexString(254); // converte 254 para

hexa

System.out.println("254 igual a " + s3); // "254 igual a fe"

Page 247: 57547801-Scjp

247

Autoboxing

Permite manipular os Wrappers de forma mais conveniente

No Java 1.4:Integer y = new Integer(567);int x = y.intValue();x++;y = new Integer(x);System.out.println("y = " + y); // y = 568

No Java 5:Integer y = new Integer(567);y++;System.out.println("y = " + y); // y = 568

Page 248: 57547801-Scjp

248

Autoboxing

Exemplos de usoclass UseBoxing {

public static void main(String [] args) {UseBoxing u = new UseBoxing();u.go(5);

}boolean go(Integer i) { // faz o boxing do int que foi passadoBoolean ifSo = true; // faz o boxing do literal booleanoShort s = 300; // faz o boxing do literal primitivo

if(ifSo) { // faz o unboxingSystem.out.println(++s); // faz o unboxing, incrementa e

depois// faz o boxing}

return !ifSo; // faz o unboxing (retorno eh primitivo)}

}

Page 249: 57547801-Scjp

249

Sobrecarga de métodos – Parte 2

Exemplo 1 - Sobrecarga com Autoboxingclass AddBoxing {

static void go(Integer x) { System.out.println("Integer"); }

static void go(long x) { System.out.println("long"); }

public static void main(String [] args) {

int i = 5;

go(i); // qual go() sera invocado?

}

}

Saída do programa:long

Page 250: 57547801-Scjp

250

Sobrecarga de métodos – Parte 2

Exemplo 3 - Sobrecarga com Var-argsclass AddVarargs {

static void go(int x, int y) { System.out.println("int,int");}

static void go(byte... x) { System.out.println("byte... "); }

public static void main(String[] args) {byte b = 5;go(b,b); // qual go() sera invocado?}

}

Saída do programa:int,int

Page 251: 57547801-Scjp

251

Sobrecarga de métodos – Parte 2

Exemplo 4 - Sobrecarga com Autoboxing e Var-args

class BoxOrVararg {static void go(Byte x, Byte y){ System.out.println("Byte, Byte"); }static void go(byte... x) { System.out.println("byte... "); }public static void main(String [] args) {

byte b = 5;go(b,b); // qual go() sera invocado?

}}

Saída do programa:Byte, Byte

Page 252: 57547801-Scjp

252

Garbage Collection

O garbage collector remove da heap os objetos que não são mais utilizados, liberando espaço na memória

Utiliza-se o método System.gc() para invocar o garbage collector, mas a sua execução não é garantida Essa chamada apenas solicita que o garbage collector seja

executado

A decisão de quando ele será executado é da JVM

Um objeto será alvo do garbage collector caso não possa mais ser acessado, ou seja, quando não existirem mais referências para ele

Page 253: 57547801-Scjp

253

Objetivos

Utilizar coleções

Utilizar o pacote java.util para ordenação e busca

Utilizar Comparable e Comparator

Sobrescrever os métodos equals() e hashCode()

Distinguir equals() de = =

Utilizar as versões genéricas das coleções, incluindo Set,List e Map

Implementar métodos genéricos e utilizar tipos genéricos

Page 254: 57547801-Scjp

254

Coleções

Três significados para “collection” em Java collection : uma estrutura de dados que armazena

referências para objetos

Collection : interface contida no pacote java.util

Collections : uma classe que contém métodos úteis (estáticos)para coleções

Page 255: 57547801-Scjp

255

Coleções

Operações básicas Adicionar objetos ( add () )

Remover objetos ( remove () )

Verificar se um determinado objeto faz parte dacoleção ( contains () )

Buscar objetos

Percorrer a coleção ( iterator () )

Page 256: 57547801-Scjp

256

Coleções

Os quatro tipos de coleções cobrados no exame são: Listas (List)

Conjuntos (Set)

Mapeamentos chave-valor (Map)

Filas (Queue)

Page 257: 57547801-Scjp

257

Coleções

Page 258: 57547801-Scjp

258

Coleções

List Interface que herda da interface Collection Pode ter elementos duplicados Usa índices Mantém a ordem de inserção Classes que implementam List cobradas no exame

ArrayList É um array que pode crescer dinamicamente Fornece iteração rápida e rápido acesso aleatório

Vector É um ArrayList mais lento (métodos são synchronized)

LinkedList É uma lista duplamente encadeada Boa para adicionar elementos às extremidades, isto é, pilhas e filas

Page 259: 57547801-Scjp

259

Coleções

Usando List – Exemplo com ArrayListimport java.util.*;

public class TestArrayList {

public static void main(String[] args) {

List<String> test = new ArrayList<String>();

String s = "hi";

test.add("string"); // adiciona elemento

test.add(s);

test.add(s+s);

System.out.println(test.size()); // imprime tamanho

System.out.println(test.contains(42)); // verifica existencia

System.out.println(test.contains("hihi"));

test.remove("hi"); // remove elemento

System.out.println(test.size());}

}

Page 260: 57547801-Scjp

260

Coleções

Iteração com iterator A iteração em uma coleção pode ser feita ou com o

enhanced for (foreach) ou então utilizando um objetoIterator e seus métodos hasNext() e next()

hasNext() determina se existem mais elementos; oiterador não se move

next() retorna o próximo elemento e move o iteradorpara frente

Page 261: 57547801-Scjp

261

Coleções

Set Interface que herda da interface Collection Não permite elementos duplicados ( utiliza equals () ) Pode ou não ser ordenado Pode ou não manter a ordem de inserção Classes que implementam Set cobradas no exame: HashSet

Acesso rápido, não mantém ordem de inserção

LinkedHashSet A iteração é feita pela ordem de inserção

TreeSet Mantém os elementos ordenados

Page 262: 57547801-Scjp

262

Coleções

Usando Setimport java.util.*;class SetTest {

public static void main(String[] args) {boolean[] ba = new boolean[5];Set s = new HashSet();ba[0] = s.add("a");ba[1] = s.add(new Integer(42));ba[2] = s.add("b");ba[3] = s.add("a");ba[4] = s.add(new Object());for(int x=0; x<ba.length; x++)System.out.print(ba[x] + " ");

System.out.println("\n");for(Object o : s)System.out.print(o + " ");

}}

Page 263: 57547801-Scjp

263

Coleções

Map Interface que não herda da interface Collection

Não permite chaves duplicadas ( utiliza equals () )

Pode ou não ser ordenado

Pode ou não manter a ordem de inserção

Page 264: 57547801-Scjp

264

Coleções

Map Classes que implementam Map cobradas no exame

HashMap Não mantém ordem de inserção

Permite uma chave nula e vários valores nulos

Hashtable É um HashMap mais lento (como Vector, devido aos métodos synchronized)

Não permite nem valores nem chaves nulas

LinkedHashMap A iteração é feita pela ordem de inserção ou acesso (LRU – least-recently used)

Permite uma chave nula e vários valores nulos

TreeMap Mantém os elementos ordenados

Page 265: 57547801-Scjp

265

Coleções

Usando Mapimport java.util.*;class Dog {

public Dog(String n) { name = n; }public String name;public boolean equals(Object o) {if((o instanceof Dog) && (((Dog)o).name == name)) {return true;} else {

return false;}

}public int hashCode() {return name.length(); }

}class Cat { }enum Pets {DOG, CAT, HORSE }

Page 266: 57547801-Scjp

266

Coleções

Usando Map (continuação)class MapTest {

public static void main(String[] args) {Map<Object, Object> m = new HashMap<Object, Object>();m.put("k1", new Dog("aiko"));m.put("k2", Pets.DOG);m.put(Pets.CAT, "CAT key");Dog d1 = new Dog("clover");m.put(d1, "Dog key");m.put(new Cat(), "Cat key");System.out.println(m.get("k1"));String k2 = "k2";System.out.println(m.get(k2));Pets p = Pets.CAT;System.out.println(m.get(p));System.out.println(m.get(d1));System.out.println(m.get(new Cat()));System.out.println(m.size());

}}

Page 267: 57547801-Scjp

267

Coleções

Queue Interface que herda da interface Collection

Mantém os elementos ordenados por FIFO ou por prioridade

Classes que implementam Queue cobradas no exame:

PriorityQueue Fila ordenada pela prioridade dos elementos

LinkedList Fila FIFO (first-in, first-out)

Page 268: 57547801-Scjp

268

Coleções

Usando PriorityQueueimport java.util.*;

class PQTest {

public static void main(String[] args) {

int[] ia = {1,5,3,7,6,9,8 };

PriorityQueue<Integer> pq1 = new PriorityQueue<Integer>(); // usa ordem natural

for(int x : ia)

pq1.offer(x); // insere na fila

for(int x : ia)

System.out.print(pq1.poll() + " ");//remove da fila

System.out.println("");

}

}

Page 269: 57547801-Scjp

269

Coleções

Métodos de PriorityQueue offer() – adiciona um elemento à fila

poll() – remove a cabeça da fila

peek() – retorna o valor da cabeça da fila (sem remover)

Page 270: 57547801-Scjp

270

Coleções

Ordenação e Busca As classes Collections e Arrays fornecem métodos estáticos

para ordenação e busca em coleções e arrays, respectivamente: sort() : Ordena os elementos, alterando a coleção ou array existente

binarySearch(): Faz uma busca binária em uma coleção ou arrayordenado

Page 271: 57547801-Scjp

271

Coleções

Ordenação – Exemploimport java.util.*;class TestSort1 {

public static void main(String[] args) {ArrayList<String> cidades = new ArrayList<String>();cidades.add("Denver");cidades.add("Boulder");cidades.add("Vail");cidades.add("Aspen");cidades.add("Telluride");System.out.println("desordenada " + cidades);Collections.sort(cidades);System.out.println("ordenada " + cidades);

}}

Resultado:desordenada [Denver, Boulder, Vail, Aspen, Telluride]ordenada [Aspen, Boulder, Denver, Telluride, Vail]

Page 272: 57547801-Scjp

272

Coleções

Ordenação utilizando Collections.sort() – Forma 1 O método sort() recebe um parâmetro do tipo List

Os elementos armazenados na lista devem implementar uma interface chamada Comparable

A classe String implementa Comparable, por essa razão é possível ordenar oArrayList cidades do exemplo anterior

class DVDInfo {

String title;

String genre;

String leadActor;

DVDInfo(String t, String g, String a) {

title = t; genre = g; leadActor = a;

}

}

Page 273: 57547801-Scjp

273

Coleções

Implementando a interface Comparableclass DVDInfo implements Comparable<DVDInfo> {

String title;String genre;String leadActor;DVDInfo(String t, String g, String a) {

title = t; genre = g; leadActor = a;}public int compareTo(DVDInfo d) {

return title.compareTo(d.getTitle());}public String getTitle() {

return title;}

}

O método compareTo() retorna um inteiro: Negativo – Se o objeto é menor que o outro objeto Zero – Se o objeto é igual ao outro objeto Positivo – Se o objeto é maior que o outro objeto

Page 274: 57547801-Scjp

274

Coleções

Problemas com a forma 1 Ficamos restritos a um único critério de ordenação: não

existe outro método para implementar na interface Comparable

Para incluir uma nova ordenação, é preciso alterar o código do método compareTo()

Se surgir uma nova classe cujos objetos precisem ser ordenados, temos que alterar o seu código para implementar a interface Comparable

Page 275: 57547801-Scjp

275

Coleções

Ordenação utilizando Collections.sort() – Forma 2 Há uma versão sobrecarregada do método sort() que

recebe um List e um Comparator

A interface Comparator define o método compare(), que funciona com as mesmas regras do métodocompareTo(), porém recebe como parâmetro os dois objetos que serão comparados

Page 276: 57547801-Scjp

276

Coleções

Busca – Exemploimport java.util.*;class SearchObjArray {

public static void main(String [] args) {String [] sa = {"one", "two", "three", "four"};Arrays.sort(sa);for(String s : sa)System.out.print(s + " ");System.out.println("\none = " +

Arrays.binarySearch(sa,"one"));}

}

Se a busca encontrou o elemento procurado, retorna o índice do elemento (iniciado em 0)

Uma busca sem sucesso retorna um int que representa o ponto de inserção (iniciado em -1)

Para que a busca binária seja executada com sucesso, o array ou lista deve estar ordenado!

Page 277: 57547801-Scjp

277

Método equals( )

É um método público da classe java.lang.Objectpublic boolean equals(Object obj) Utilizamos equals() para que dois objetos diferentes

possam ser considerados iguais

equals() serve para determinar se dois objetos são semanticamente equivalentes

= = serve para determinar se duas variáveis de referência referem-se ao mesmo objeto

Page 278: 57547801-Scjp

278

Método equals( )

Exemplo 1public class TesteEquals0{

public static void main(String[] args){Pessoa p1 = new Pessoa("123");Pessoa p2 = p1;System.out.println("p1.equals(p2)? "+ (p1.equals(p2)));System.out.println("p1 == p2? "+ (p1 == p2));}

}class Pessoa{

private String cpf;Pessoa(String sCpf){cpf = sCpf;}public String getCpf(){return cpf;}

}

Page 279: 57547801-Scjp

279

Método equals( )

Exemplo 1 – Resultado

p1.equals(p2)? True

p1 = = p2? True

Pela implementação de Object, dois objetos só vão ser considerados semanticamente equivalentes se as referências “apontarem” para o mesmo objeto!

Page 280: 57547801-Scjp

280

Método equals( )

Exemplo 2public class TesteEquals1{

public static void main(String[] args){Pessoa p1 = new Pessoa("123");Pessoa p2 = new Pessoa("123");System.out.println("p1.equals(p2)? "+ (p1.equals(p2)));System.out.println("p1 == p2? "+ (p1 == p2));}

}class Pessoa{

private String cpf;Pessoa(String sCpf){

cpf = sCpf;}public String getCpf(){

return cpf;}

}

Resultado

p1.equals(p2)? false

p1 == p2? false

Page 281: 57547801-Scjp

281

Método equals( )

Exemplo 3public class TesteEquals{

public static void main(String[] args){Pessoa p1 = new Pessoa("123");Pessoa p2 = new Pessoa("123");System.out.println("p1.equals(p2)? "+ (p1.equals(p2)));System.out.println("p1 == p2? "+ (p1 == p2));

}}class Pessoa{

private String cpf;Pessoa(String sCpf) { cpf = sCpf; }public String getCpf() { return cpf; }public boolean equals(Object o){if ((o instanceof Pessoa) && (((Pessoa)o).getCpf().equals(cpf)))

return true;return false;

}}

Page 282: 57547801-Scjp

282

Método equals( )

Resultado

p1.equals(p2)? true

p1 == p2? false

Page 283: 57547801-Scjp

283

Método equals( )

equals() X hashing Se equals() não for sobrescrito, os objetos não poderão

ser chaves de hash Strings e wrappers (Integer, Long, Boolean etc)

sobrescrevem equals() e portanto são boas chaves de hash

Sobrescrevendo equals() Utilizar o operador instanceof para ter certeza que a

classe do objeto passado por parâmetro é apropriada Comparar os atributos significativos dos objetos

Page 284: 57547801-Scjp

284

Método equals( )

Contrato de equals() Reflexivo: x.equals(x) é verdadeiro

Simétrico: x.equals(y) é verdadeiro se e somente se y.equals(x) é verdadeiro

Transitivo: Se x.equals(y) é verdadeiro e y.equals(z) é verdadeiro, então x.equals(z) é verdadeiro

Consistente: Múltiplas chamadas a x.equals(y) sempre retornarão o mesmo resultado, dado que as informações usadas na comparação não se alterem

Nulo: Se x é não nulo, então x.equals(null) é falso

Page 285: 57547801-Scjp

285

Método equals

equals() tem um contrato conjunto comhashCode() Se x.equals(y) é verdadeiro, então x.hashCode() = =

y.hashCode() é verdadeiro

Se dois objetos são semanticamente equivalentes, ohashcode deles tem que ser igual

Se equals() for sobrescrito, hashCode() também deve ser sobrescrito

Page 286: 57547801-Scjp

286

Método hashCode( )

É um método público da classe java.lang.Objectpublic int hashCode()

Retorna um valor inteiro associado ao objeto, deforma que o objeto possa ser utilizado em coleções que usam hashing

Há questões no exame que pedem para identificar se uma determinada implementação do métodohashCode() é adequada

Page 287: 57547801-Scjp

287

Método hashCode( )

Uso de hashCode – Exemplo

Page 288: 57547801-Scjp

288

Método hashCode( )

Passos para a adição de um novo elemento1. Localizar o bucket utilizando o hashCode

2. Inserir o objeto no bucket encontrado

Passos para a busca de um elemento1. Utilizar o hashCode para encontrar o bucket correto

2. Utilizar o método equals() para encontrar o objeto dentro do bucket

Page 289: 57547801-Scjp

289

Método hashCode

Exemplo: Valor do hashCode dos objetos da classe Pessoapublic class TesteHashCode0{

public static void main(String[] args){

Pessoa p1 = new Pessoa("123");Pessoa p2 = new Pessoa("123");System.out.println("p1.equals(p2)? "+ (p1.equals(p2)));System.out.println("p1 == p2? "+ (p1 == p2));System.out.println("p1.hashCode() == p2.hashCode()? "+

(p1.hashCode() ==p2.hashCode()));System.out.println("p1.hashCode() == "+ p1.hashCode());System.out.println("p2.hashCode() == "+ p2.hashCode());

}}class Pessoa{

private String cpf;Pessoa(String sCpf) { cpf = sCpf; }public String getCpf() { return cpf; }public boolean equals(Object o){

if ((o instanceof Pessoa) && (((Pessoa)o).getCpf().equals(cpf)))

return true;return false;

Page 290: 57547801-Scjp

290

Método hashCode( )

Resultado:p1.equals(p2)? true

p1 == p2? false

p1.hashCode() == p2.hashCode()? false

p1.hashCode() == 26022015

p2.hashCode() == 3541984

Page 291: 57547801-Scjp

291

Método hashCode( )

Implementando hashCode()class HasHash {

public int x;HasHash(int xVal) { x = xVal; }public boolean equals(Object o) {

HasHash h = (HasHash) o;if (h.x == this.x) {return true;} else {return false;}

}public int hashCode() {

return (x * 17);}

}

Page 292: 57547801-Scjp

292

Método hashCode( )

Contrato de hashCode() Consistente: múltiplas chamadas a x.hashCode() retornam o

mesmo valor inteiro

Se x.equals(y) é verdadeiro, então x.hashCode() == y.hashCode() é verdadeiro

Se x.equals(y) é falso, então x.hashCode() == y.hashCode() pode ser ou verdadeiro ou falso, mas falso tende a ser mais eficiente

Page 293: 57547801-Scjp

293

Método hashCode( )

Sobrescrevendo hashCode() Variáveis transientes (palavra-chave transient) não são

adequadas para equals() e hashCode()

Uma sobrescrita adequada de hashCode() respeita o contrato de hashCode()

Uma sobrescrita eficiente de hashCode() distribui os elementos uniformemente pelos buckets

É permitido que um método hashCode() retorne o mesmo valor para todas as instâncias (embora muito ineficiente)

Page 294: 57547801-Scjp

294

Generics

Permite que o programador force, em tempo de compilação, os tipos dos elementos inseridos em uma coleção (type safety)

ArrayList de Strings, antes do Java 5List myList = new ArrayList();

myList.add("Fred"); // OK, insiro uma String

myList.add(new Dog()); // OK, tambem posso inserir um Dog

myList.add(new Integer(42)); // OK, posso inserir um Integer

ArrayList de Strings, a partir do Java 5

List<String> myList = new ArrayList<String>();

myList.add("Fred"); // OK, insiro uma String

myList.add(new Dog()); // erro de compilacao!!

Page 295: 57547801-Scjp

295

Generics

Quando uma coleção genérica é usada, não é necessária uma operação de cast para obter os elementos (get) da coleção. Com coleções não-genéricas, o cast é requerido

List<String> gList = new ArrayList<String>();

List list = new ArrayList();

// mais codigo que adiciona elementos

String s = gList.get(0); // nao necessita de cast

String s = (String)list.get(0); // cast requerido

Page 296: 57547801-Scjp

296

Generics

Misturando coleções genéricas com não-genéricas – Exemplo 1import java.util.*;public class TestLegacy {

public static void main(String[] args) {

List<Integer> myList = new ArrayList<Integer>();myList.add(4);myList.add(6);Adder adder = new Adder();int total = adder.addAll(myList);System.out.println(total);

}}class Adder { // codigo legado

int addAll(List list) {Iterator it = list.iterator();int total = 0;

while (it.hasNext()) {int i = ((Integer)it.next()).intValue();total += i;

}return total;}}

Page 297: 57547801-Scjp

297

Generics

Misturando coleções genéricas com não-genéricas – Exemplo 2import java.util.*;public class TestBadLegacy {

public static void main(String[] args) {List<Integer> myList = new ArrayList<Integer>();myList.add(4);myList.add(6);Inserter in = new Inserter();in.insert(myList);

}}class Inserter { // codigo legado

void insert(List list) {list.add(new Integer(42)); // OKlist.add(new String(“42”)); // Tambem OK!

}}

Page 298: 57547801-Scjp

298

Generics

Ao compilarmos o Exemplo 2, o compilador exibe a seguinte mensagem dewarning:

Note: TestBadLegacy.java uses unchecked or unsafe operations.

Note: Recompile with -Xlint:unchecked for details.

Se o compilador reconhecer que um código que não é “type safe” pode alterar uma coleção originalmente “type-safe”, uma mensagem de warning será lançada

No Exemplo 2, ambas as chamadas ao método add() na coleção recebida porparâmetro são consideradas operações não seguras e geram warning.

As informações de tipos genéricos não existem em tempo de execução – as checagens são feitas apenas em tempo de compilação. Misturar generics com código legado

Page 299: 57547801-Scjp

299

Generics

Polimorfismo e Generics Atribuições polimórficas aplicam-se apenas ao tipo base, não se aplicam ao

tipo genérico

O tipo declarado na variável (lado esquerdo) deve casar com o tipo do objeto (lado direito)

List<Animal> aList = new ArrayList<Animal>(); // ok

List<Animal> aList = new ArrayList<Dog>(); // erro

Um ArrayList pode ser atribuído a uma variável List, porém um ArrayList de Dog não pode ser atribuído a um List de Animal

A regra da atribuição polimórfica aplica-se a toda situação na qual uma atribuição puder ser realizada. Os seguintes exemplos são ilegais:

void foo(List<Animal> aList) { } // não pode receber umList<Cao>

List<Animal> bar() { } // não pode retornar um List<Cao>

Page 300: 57547801-Scjp

300

Generics

Polimorfismo e Generics Um ArrayList<Animal> pode armazenar referências

para objetos do tipo

Cao, Gato ou qualquer outro subtipo de Animal (ou se Animal é uma interface, qualquer classe que a implementa)

List<Animal> animals = new ArrayList<Animal>();

animals.add(new Cat()); // OK

animals.add(new Dog()); // OK

Page 301: 57547801-Scjp

301

Generics

Polimorfismo e Generics – Exemplo 1abstract class Animal {

public abstract void checkup();}class Dog extends Animal {

public void checkup() {System.out.println("Dog checkup");}

}class Cat extends Animal {

public void checkup() {System.out.println("Cat checkup");}

}class Bird extends Animal {

public void checkup() {System.out.println("Bird checkup");}

}

Page 302: 57547801-Scjp

302

Generics

Polimorfismo e Generics – Exemplo 1 (continuação)public class AnimalDoctorGeneric {

public void checkAnimals(List<Animal> animals) {for(Animal a : animals) {

a.checkup();}

}public static void main(String[] args) {

List<Dog> dogs = new ArrayList<Dog>();dogs.add(new Dog());dogs.add(new Dog());List<Cat> cats = new ArrayList<Cat>();cats.add(new Cat());cats.add(new Cat());List<Bird> birds = new ArrayList<Bird>();birds.add(new Bird());AnimalDoctorGeneric doc = new AnimalDoctorGeneric();doc.checkAnimals(dogs);doc.checkAnimals(cats);doc.checkAnimals(birds);

}}

Page 303: 57547801-Scjp

303

Generics

Polimorfismo e Generics – Exemplo 1 : Erro de compilação

AnimalDoctorGeneric.java:36: checkAnimals(java.util.List<Animal>) in

AnimalDoctorGeneric cannot be applied to (java.util.List<Dog>)

doc.checkAnimals(dogs);

^

AnimalDoctorGeneric.java:37: checkAnimals(java.util.List<Animal>) in

AnimalDoctorGeneric cannot be applied to (java.util .List<Cat>)

doc.checkAnimals(cats);

^

AnimalDoctorGeneric.java:38: checkAnimals(java.util.List<Animal>) in

AnimalDoctorGeneric cannot be applied to (java.util.List<Bird>)

doc.checkAnimals(birds);

^

3 errors

Page 304: 57547801-Scjp

304

Generics

Polimorfismo e Generics – Exemplo 1 : Correçãopublic class AnimalDoctorGeneric {

public void checkAnimals(List<? extends Animal> animals) {for(Animal a : animals) {

a.checkup();}

}public static void main(String[] args) {

List<Dog> dogs = new ArrayList<Dog>();dogs.add(new Dog());dogs.add(new Dog());List<Cat> cats = new ArrayList<Cat>();cats.add(new Cat());cats.add(new Cat());List<Bird> birds = new ArrayList<Bird>();birds.add(new Bird());AnimalDoctorGeneric doc = new AnimalDoctorGeneric();doc.checkAnimals(dogs);doc.checkAnimals(cats);doc.checkAnimals(birds);

}}

Page 305: 57547801-Scjp

305

Generics

O uso do caracter coringa “?” (wildcard) permite que o método aceite qualquer

subtipo do tipo declarado no argumento:

void addD(List<Cao> d) {} // pode receber apenas <Cao>

void addD(List<? extends Cao> d) {} // recebe <Cao> ou <Beagle>

A palavra-chave extends é usada com sentido de “extends” ou “implements”. Então em <? extends Cao>, Cao pode ser uma classe ou uma interface

Ao usar List<?> ou List<? extends Cao>, a coleção pode ser acessada mas não modificada

Page 306: 57547801-Scjp

306

Generics

Utilizar o caracter coringa combinado com a palavra-chave super permite que a coleção seja acessada e modificada (add() é permitido)

No Exemplo 2, o compilador aceita qualquer lista (subtipo de List) cujo tipo genérico seja Dog ou um supertipo de Dog

Uma coleção declarada com qualquer supertipo deDog pode aceitar um Dog como elemento (regra da atribuição)

Page 307: 57547801-Scjp

307

Generics

Declarações de tipos genéricos O uso de Generics também permite que o programador defina, em

tempo de compilação, os tipos usados em classes e métodos declarados com tipos genéricos

Page 308: 57547801-Scjp

308

Generics

Declarações de tipos genéricos – Exemploimport java.util.*;public class RentalGeneric<T> {private List<T> rentalPool;private int maxNum;

public RentalGeneric(int maxNum, List<T> rentalPool) {this.maxNum = maxNum;this.rentalPool = rentalPool;

}public T getRental() {

return rentalPool.get(0);}public void returnRental(T returnedThing) {

rentalPool.add(returnedThing);}

}class Car { }

Page 309: 57547801-Scjp

309

Generics

Declarações de tipos genéricos – Exemplo (continuação)class TestRental {

public static void main (String[] args) {

Car c1 = new Car();

Car c2 = new Car();

List<Car> carList = new ArrayList<Car>();

carList.add(c1);

carList.add(c2);

RentalGeneric<Car> carRental = new RentalGeneric<Car>(2,carList);

Car carToRent = carRental.getRental();

carRental.returnRental(carToRent);

}

}

Page 310: 57547801-Scjp

310

Generics

O tipo declarado na classe pode ser utilizado de várias maneiras:

public class TestGenerics<T> {

T anInstance;

T [] anArrayOfTs;

TestGenerics(T anInstance) {

this.anInstance = anInstance;

}

T getT() {

return anInstance;

}

}

Page 311: 57547801-Scjp

311

Generics

É permitido declarar um método genérico usando um tipo não definido na classe:

public <T> void makeList(T t) { }

No código acima, T não é o tipo de retorno. Este método retorna void, e para usar T dentro do argumento do método deve ser declarado <T>, o que deve ocorrer ANTES do tipo de retorno

Page 312: 57547801-Scjp

312

Generics

A palavra-chave extends também pode ser utilizada na declaração do tipo genérico da classe ou método, para determinar o conjunto de tipos que podem ser aceitos:

public class AnimalHolder<T extends Animal> {

T animal;

public static void main(String[] args) {AnimalHolder<Dog> dogHolder = new AnimalHolder<Dog>(); // OK

AnimalHolder<Integer> x = new AnimalHolder<Integer>(); // Erro!

}

}

public <T extends Number> void makeArrayList(T t)

Page 313: 57547801-Scjp

313

Objetivos

Utilizar String, StringBuilder e StringBuffer

Desenvolver código de leitura e escrita de arquivos utilizando o pacote java.io

Utilizar o pacote java.io para implementarserialização de objetos

Implementar código que trabalhe com datas, números e valores monetários

Utilizar expressões regulares

Page 314: 57547801-Scjp

314

String, StringBuilder e StringBuffer

Criando uma nova String

Exemplo 1String s = new String();

s = "abcdef";

Exemplo 2String s = new String("abcdef");

Exemplo 3String s = "abcdef";

Page 315: 57547801-Scjp

315

String, StringBuilder e StringBuffer

Depois que um objeto String é criado, ele nunca mais pode ser alterado Variáveis de referência para objetos String não são

imutáveis

Se um novo objeto String for criado e não for atribuído a nenhuma variável, ele será perdido

Page 316: 57547801-Scjp

316

String, StringBuilder e StringBuffer

Exemplo 1class StringTest {

public static void main(String [] args) {String x = "Java";String y = x;System.out.println("y string = " + y);x = x + " Bean";System.out.println("y string = " + y);

}}

Resultadoy string = Javay string = Java

Page 317: 57547801-Scjp

317

String, StringBuilder e StringBuffer

Exemplo 2String s = "Fred";

String t = s;

t.toUpperCase();

System.out.println(s);

System.out.println(t);

ResultadoFred

Fred

Page 318: 57547801-Scjp

318

String, StringBuilder e StringBuffer

Exemplo 3String x = "Java";

x = x.concat(" Rules!");

System.out.println("x = " + x);

x.toLowerCase();

System.out.println("x = " + x);

x = x.toLowerCase();

System.out.println("x = " + x);

Resultadox = Java Rules!

x = Java Rules!

x = java rules!

Page 319: 57547801-Scjp

319

String, StringBuilder e StringBuffer

Métodos importantes da classe String charAt() – Retorna o caracter localizado no índice informado concat() – Concatena duas Strings (idem ao “+”) equalsIgnoreCase() – Determina a igualdade de duas Strings, ignorando

maiúsculas e minúsculas length() – Retorna o número de caracteres da String replace() – Substitui ocorrências de um caracter por um novo caracter substring() – Retorna um pedaço da String toLowerCase() – Retorna uma String com todos os caracteres em

minúsculas toString() – Retorna o valor da String toUpperCase() – Retorna uma String com todos os caracteres em

maiúsculas trim() – Remove espaços das “extremidades” da String

Page 320: 57547801-Scjp

320

String, StringBuilder e StringBuffer

As classes java.lang.StringBuffer ejava.lang.StringBuilder devem ser usadas quando houver necessidade de muita manipulação deStrings

Utilizar a classe String nesse cenário acabaria gerando muitos objetos String abandonados na memória

Page 321: 57547801-Scjp

321

String, StringBuilder e StringBuffer

Código que usa StringString x = "abc";

x = x.concat("def");

System.out.println("x = " + x); // x = abcdef

Código que usa StringBufferStringBuffer sb = new StringBuffer("abc");

sb.append("def");

System.out.println("sb = " + sb); // sb = abcdef

Page 322: 57547801-Scjp

322

String, StringBuilder e StringBuffer

A classe StringBuffer tem a mesma API que a classeStringBuilder, porém os métodos de StringBuilder não sãosynchronized Os métodos de StringBuilder têm execução mais rápida que os métodos

de StringBuffer

Utilizar StringBuilder sempre que possível!

Os seguintes pontos aplicam-se tanto a StringBuffer quanto aStringBuilder: Ambos são mutáveis – podem ser alterados sem a necessidade de

criação de um novo objeto

O método equals() não é sobrescrito em nenhuma das duas classes.

Page 323: 57547801-Scjp

323

String, StringBuilder e StringBuffer

Métodos importantes das classes StringBuffer/StringBuilder: append()

delete()

insert()

reverse()

toString()

Page 324: 57547801-Scjp

324

Java I/O

As classes do pacote java.io cobradas pelo exame são: File

FileReader

BufferedReader

FileWriter

BufferedWriter

PrintWriter

Page 325: 57547801-Scjp

325

Java I/O

Exemplo:import java.io.*;

class Writer1 {

public static void main(String [] args) {

try {

boolean newFile = false;

File file = new File("fileWrite1.txt");

System.out.println(file.exists());

newFile = file.createNewFile();

System.out.println(newFile);

System.out.println(file.exists());

} catch(IOException e) { }

}

}

Page 326: 57547801-Scjp

326

Java I/O

Objetos da classe File podem representar arquivos ou diretórios

A classe File permite gerenciar (criar, renomear e excluir) arquivos e diretórios

A criação de um novo objeto File não implica na criação de um novo arquivo no disco Os métodos createNewFile() e mkDir() criam novos

itens no sistema de arquivos

Page 327: 57547801-Scjp

327

Java I/O

Leitura e escrita com FileReader e FileWriter – Exemploimport java.io.*;class Writer2 {

public static void main(String [] args) {char[] in = new char[50];int size = 0;

try {File file = new File("fileWrite2.txt");FileWriter fw = new FileWriter(file); // cria um arquivo no discofw.write("howdy\nfolks\n");fw.flush();fw.close();FileReader fr = new FileReader(file);size = fr.read(in); // le o arquivo inteiro!System.out.print(size + " "); // qtd bytes lidosfor(char c : in)System.out.print(c);fr.close();

} catch(IOException e) { }}

}

Page 328: 57547801-Scjp

328

Java I/O

O código do exemplo anterior tem dois problemas: Tivemos que inserir quebras de linha manualmente

Tivemos que criar um buffer de tamanho fixo para armazenar o conteúdo lido do arquivo

FileWriter e FileReader são classes de baixo nível. Elas podem ser usadas para leitura e escrita de arquivos, porém geralmente são utilizadas encadeadas a outros objetos de java.io

Page 329: 57547801-Scjp

329

Java I/O

Combinando as classes de java.io As classes no pacote java.io foram projetadas para

serem usadas encadeadas com outras classes

É comum encapsular um FileReader em umBufferedReader, de forma a ter acesso a métodos de mais alto nível

É comum encapsular um FileWriter em umBufferedWriter, de forma a ter acesso a métodos de mais alto nível

Page 330: 57547801-Scjp

330

Java I/O

Combinando as classes de java.io – Exemplo Escrita

File file = new File("fileWrite2.txt");FileWriter fw = new FileWriter(file);PrintWriter pw = new PrintWriter(fw);pw.println("howdy");pw.println("folks");

LeituraFile file = new File("fileWrite2.txt");FileReader fr = new FileReader(file);BufferedReader br = new BufferedReader(fr);String data = br.readLine();

Page 331: 57547801-Scjp

331

Java I/O

Trabalhando com diretórios – Exemplo 1File myDir = new File("mydir");

myDir.mkdir();

File myFile = new File(myDir, "myFile.txt");

myFile.createNewFile();

Page 332: 57547801-Scjp

332

Java I/O

Trabalhando com diretórios – Exemplo 2 Suponha que exista um diretório chamado

“pasta1” contendo um arquivo chamado “lista.txt”File existingDir = new File(“pasta1");System.out.println(existingDir.isDirectory());File existingDirFile = new File(existingDir, “lista.txt");System.out.println (existingDirFile.isFile());FileReader fr = new FileReader(existingDirFile);BufferedReader br = new BufferedReader(fr);String s;while( (s = br.readLine()) != null)

System.out.println(s);br.close();

Page 333: 57547801-Scjp

333

Serialização de objetos

Mecanismo fornecido pela linguagem para persistir o estado dos objetos Permite salvar o objeto e as suas variáveis de instância

de uma forma simples

Variáveis transient não são serializadas (persistidas)!

Page 334: 57547801-Scjp

334

Serialização de objetos

API básica ObjectOutputStream.writeObject() // serializa

ObjectInputStream.readObject() // deserializa

Page 335: 57547801-Scjp

335

Serialização de objetos

Exemplo:import java.io.*;class Cat implements Serializable { }public class SerializeCat {

public static void main(String[] args) {Cat c = new Cat();

try {FileOutputStream fs = new FileOutputStream("testSer.ser");ObjectOutputStream os = new ObjectOutputStream(fs);os.writeObject(c);os.close();} catch (Exception e) { e.printStackTrace(); }try {FileInputStream fis = new FileInputStream("testSer.ser");ObjectInputStream ois = new ObjectInputStream(fis);c = (Cat) ois.readObject();ois.close();} catch (Exception e) { e.printStackTrace(); }

}}

Page 336: 57547801-Scjp

336

Serialização de objetos

Uma classe deve implementar a interfaceSerializable para que seus objetos sejamserializados A interface Serializable é apenas de marcação; não

existem métodos para serem implementados

FileOutputStream e FileInputStream são usadas para criar as streams de baixo nível que as classesObjectXxxStream utilizam

Page 337: 57547801-Scjp

337

Serialização de objetos

Na serialização de Dog, seu objeto Collar também será salvo?

class Dog implements Serializable {private Collar theCollar;

private int dogSize;public Dog(Collar collar, int size) {theCollar = collar;dogSize = size;}public Collar getCollar() { return theCollar; }

}class Collar implements Serializable {

private int collarSize;public Collar(int size) { collarSize = size; }public int getCollarSize() { return collarSize; }

}

Page 338: 57547801-Scjp

338

Serialização de objetos

O mecanismo de serialização de Java salva e restaura automaticamente todo o grafo de objetos

Page 339: 57547801-Scjp

339

Serialização de objetos

E se a classe Collar não puder ser Serializable? Opção 1: Não fazer nada. Ao tentar executar o código

da serialização, será lançada a exceçãojava.io.NotSerializableException: Collar

Opção 2: Declarar a variável Collar como transient. Dessa forma, o objeto Dog será serializado, porém o valor salvo para a variável Collar será null

Opção 3: Implementar os métodos writeObject() ereadObject(). Nesse caso, as chamadas aos métodosdefaultWriteObject() e defaultReadObject() tratarão da parte automática da serialização

Page 340: 57547801-Scjp

340

Serialização de objetos

Implementando a Opção 3class Dog implements Serializable {transient private Collar theCollar;private int dogSize;

public Dog(Collar collar, int size) {

theCollar = collar;dogSize = size;

}public Collar getCollar() { return theCollar; }private void writeObject(ObjectOutputStream os) {

try {os.defaultWriteObject();os.writeInt(theCollar.getCollarSize());} catch (Exception e) { e.printStackTrace(); }

}private void readObject(ObjectInputStream is) {

try {is.defaultReadObject();theCollar = new Collar(is.readInt());} catch (Exception e) { e.printStackTrace(); }}

}

Page 341: 57547801-Scjp

341

Datas, números e valores monetários

As classes cobradas pelo exame são: java.util.Date

java.util.Calendar

java.text.DateFormat

java.text.NumberFormat

java.util.Locale

Page 342: 57547801-Scjp

342

Datas, números e valores monetários

A classe java.util.Date Uma instância da classe Date representa uma

informação de data e hora

Internamente armazena a data e hora como um long

Representa o número de milissegundos decorridos desde 1 de janeiro de 1970

Construtores Date d1 = new Date(1000000000000L);

Date now = new Date(); // agora

Page 343: 57547801-Scjp

343

Datas, números e valores monetários

A classe java.util.Calendar A classe Calendar fornece um conjunto de métodos para

manipulação de datas, incluindo operações como obter os dias da semana ou adicionar um número de meses ou anos a uma determinada data

A classe Calendar é uma classe abstrata: Instâncias da classeCalendar devem ser criadas usando os métodos factory(getInstance())

Os métodos da classe Calendar cobrados no exame são: add(), que permite a adição/subtração de vários itens (minutos, dias, anos etc) a/de datas e roll(), que funciona como add() mas não provoca deslocamento dos componentes de maior ordem.

Page 344: 57547801-Scjp

344

Datas, números e valores monetários

A classe java.util.Calendar – Exemploimport java.util.*;class Dates2 {

public static void main(String[] args) {Date d1 = new Date(1000000000000L);System.out.println("1st date " + d1.toString());Calendar c = Calendar.getInstance();c.setTime(d1);if(c.SUNDAY == c.getFirstDayOfWeek())System.out.println("Sunday is the first day of the week");System.out.println("trillionth milli day of week is "+ c.get(c.DAY_OF_WEEK));c.add(Calendar.MONTH, 1);Date d2 = c.getTime();System.out.println("new date " + d2.toString() );

}}

Page 345: 57547801-Scjp

345

Datas, números e valores monetários

A classe java.text.DateFormat Instâncias da classe DateFormat devem ser criadas usando os

métodos factory (getInstance() e getDateInstance())

Há vários estilos de formatação disponíveis na classe DateFormat

Os estilos definidos em DateFormat podem ser aplicados em conjunto com vários Locales para criar uma gama de resultados diferentes para uma determinada data

O método DateFormat.format() é utilizado para criar Stringscontendo datas formatadas

Page 346: 57547801-Scjp

346

Datas, números e valores monetários

A classe java.text.DateFormat – Exemploimport java.text.*;import java.util.*;public class TestaDateFormat {

public static void main(String[] args) {Date d1 = new Date(1000000000000L);DateFormat[] dfa = new DateFormat[6];dfa[0] = DateFormat.getInstance();dfa[1] = DateFormat.getDateInstance();dfa[2] = DateFormat.getDateInstance(DateFormat.SHORT);dfa[3] = DateFormat.getDateInstance(DateFormat.MEDIUM);dfa[4] = DateFormat.getDateInstance(DateFormat.LONG);dfa[5] = DateFormat.getDateInstance(DateFormat.FULL);for(DateFormat df : dfa)System.out.println(df.format(d1));

}}

Page 347: 57547801-Scjp

347

Datas, números e valores monetários

A classe java.util.Locale Representa uma região definida politica, cultural e

geograficamente

ConstrutoresLocale(String language)

Locale(String language, String country)

A classe Locale é utilizada em conjunto com as classesDateFormat e NumberFormat

Ambos os objetos DateFormat e NumberFormat podem ser criados com um Locale específico e imutável

Page 348: 57547801-Scjp

348

Datas, números e valores monetários

A classe java.util.Locale – ExemploCalendar c = Calendar.getInstance();c.set(2010, 11, 14); // 14 de dezembro de 2010// (mes comeca em 0)Date d2 = c.getTime();Locale locIT = new Locale("it", "IT"); // ItaliaLocale locPT = new Locale("pt"); // PortugalLocale locUS = new Locale("en", "US"); // EUADateFormat dfBR = DateFormat.getInstance(); // Locale defaultSystem.out.println("BR " + dfBR.format(d2));DateFormat dfBRfull = DateFormat.getDateInstance(DateFormat.FULL);System.out.println("BR full " + dfBRfull.format(d2));DateFormat dfIT = DateFormat.getDateInstance(DateFormat.FULL, locIT);System.out.println("Italia " + dfIT.format(d2));DateFormat dfPT = DateFormat.getDateInstance(DateFormat.FULL, locPT);System.out.println("Portugal " + dfPT.format(d2));DateFormat dfUS = DateFormat.getDateInstance(DateFormat.FULL, locUS);System.out.println("EUA " + dfUS.format(d2));

Page 349: 57547801-Scjp

349

Datas, números e valores monetários

A classe java.text.NumberFormatfloat f1 = 123.4567f;

Locale locFR = new Locale("fr"); // França

NumberFormat[] nfa = new NumberFormat[4];

nfa[0] = NumberFormat.getInstance();

nfa[1] = NumberFormat.getInstance(locFR);

nfa[2] = NumberFormat.getCurrencyInstance();

nfa[3] = NumberFormat.getCurrencyInstance(locFR);

for(NumberFormat nf : nfa)

System.out.println(nf.format(f1));

Page 350: 57547801-Scjp

350

Parsing e formatação

Expressões Regulares (ER ou regex) São padrões utilizados para buscar dados dentro de

grandes fontes de dados

Exemplo Buscar ocorrências da String “ab” dentro da String “abaaaba”

“ab” é a expressão regular

“abaaaba” é a fonte de dados

Page 351: 57547801-Scjp

351

Parsing e formatação

Expressões Regulares com as classes Pattern e Matcher

import java.util.regex.*;class RegexSmall {

public static void main(String [] args) {Pattern p = Pattern.compile("ab"); // a expressãoMatcher m = p.matcher("abaaaba"); // a fonte de dadosboolean b = false;while(b = m.find()) {System.out.print(m.start() + " ");}

}}

Resultado: 0 4

Page 352: 57547801-Scjp

352

Parsing e formatação

regex permite a criação de padrões de busca utilizando caracteres literais ou metacaracteres

Metacaracteres permitem especificar critérios mais abstratos como “dígitos” ou “espaço”

Exemplo: Buscar ocorrências de dígitos na String a12c3e456f

Page 353: 57547801-Scjp

353

Parsing e formatação

Busca com metacaracteres – Exemplo 1import java.util.regex.*;

class RegexSmall2 {

public static void main(String [] args) {

Pattern p = Pattern.compile("\\d"); // ATENCAO ao escape

Matcher m = p.matcher("a12c3e456f");

boolean b = false;

while(b = m.find()) {

System.out.print(m.start() + " ");

}

}

}

Resultado: 1 2 4 6 7 8

Page 354: 57547801-Scjp

354

Parsing e formatação

São cobrados no exame os seguintesmetacaracteres \d : Dígito

\s : Espaço em branco

\w : Palavra (letras, dígitos ou underscore)

Page 355: 57547801-Scjp

355

Parsing e formatação

Busca com metacaracteres – Exemplo 2import java.util.regex.*;

class Regex {

public static void main(String [] args) {

Pattern p = Pattern.compile(args[0]);

Matcher m = p.matcher(args[1]);

boolean b = false;

System.out.println("Pattern is " + m.pattern());

while(b = m.find()) {

System.out.println(m.start() + " " + m.group());

}

}

}

Page 356: 57547801-Scjp

356

Parsing e formatação

Especificando conjuntos de caracteres na ER [abc] Casa com uma letra a, b ou c

[a-f] Casa com uma letra de a até f

Exemplo ER: [a-cA-c]

Fonte de dados: cafeBABE

Resultado: 0, 1, 4, 5, 6

Page 357: 57547801-Scjp

357

Parsing e formatação

Usando quantificadores “+” : uma ou mais ocorrências Exemplo

0[xX]([0-9a-fA-F])+“Procure por um 0x ou 0X, e em seguida por no mínimo uma ocorrência de um dígito hexadecimal, ignorando maiúsculas e minúsculas”

“*” : zero ou mais ocorrências “?” : uma ou nenhuma ocorrência

Exemplo\d\d\d([-\s])?\d\d\d\dCasa com1234567, 123 4567 e 123-4567

Page 358: 57547801-Scjp

358

Parsing e formatação

Tokenização É o processo de dividir um dado delimitado em

pedaços menores

Os elementos são chamados de tokens e as Strings que separam os tokens são os delimitadores

Os delimitadores podem ser caracteres simples como vírgulas ou então complexas expressões regulares

Pode ser feita com a classe Scanner ou com o método String.split()

Page 359: 57547801-Scjp

359

Parsing e formatação

Tokenização com String.split()import java.util.*;

class SplitTest {

public static void main(String[] args) {

String[] tokens = args[0].split(args[1]);

System.out.println("count " + tokens.length);

for(String s : tokens)

System.out.println(">" + s + "<");

}

}

Page 360: 57547801-Scjp

360

Parsing e formatação

O método String.split() “tokeniza” a String inteira de uma só vez, o que pode causar impacto de performance quando o dado é muito grande

A classe Scanner permite que um dado seja “tokenizado” a partir de um loop, e o processo pode ser interrompido conforme for conveniente

Page 361: 57547801-Scjp

361

Parsing e formatação

Tokenização com Scannerimport java.util.Scanner;class ScanNext {

public static void main(String [] args) {

boolean b2, b;int i;String s, hits = " ";Scanner s1 = new Scanner(args[0]); // delimitador default é

espaçoScanner s2 = new Scanner(args[0]);while(b = s1.hasNext()) {

s = s1.next(); hits += "s"; }while(b = s2.hasNext()) {

if (s2.hasNextInt()) {i = s2.nextInt(); hits += "i";

} else if (s2.hasNextBoolean()) {b2 = s2.nextBoolean(); hits += "b";

} else {s2.next(); hits += "s2";

}}

System.out.println("hits " + hits);}}

Page 362: 57547801-Scjp

362

Parsing e formatação

Formatação com format() e printf() São novidades do Java 5 dois métodos utilizados para formatar dados:

format() e printf(), ambos da classe PrintStream (o out em System.out é uma instância de PrintStream)

A formatação de dados usando printf() (ou format()) é realizada através de Strings de formatação que são associadas a argumentos primitivos ouStrings

As Strings de formatação cobradas no exame são as seguintes: Flags: “-”, “+”, “0”, “,” e “(“

Conversores: b (boolean), c (char), d (integer), f (float) e s (string)

Se o caracter de conversão não casa com o tipo do argumento, uma exceção será lançada em tempo de execução (runtime exception)

Page 363: 57547801-Scjp

363

Parsing e formatação

Sintaxe

%[arg_index$][flags][width][.precision]conversion char

ExemplosSystem.out.printf("%2$d + %1$d", 123, 456); // 456 + 123

int i1 = -123;

int i2 = 12345;

System.out.format(">%+-7d< \n", i2); // >+12345 <

System.out.printf(">%2$b + %1$5d< \n", i1, false); // >false + -123<

Page 364: 57547801-Scjp

364

Objetivos

Iniciar novas threads

Reconhecer os estados das threads e compreender o diagrama de estados

Utilizar locking para evitar acesso concorrente

Escrever código que utiliza wait(), notify() enotifyAll()

Page 365: 57547801-Scjp

365

Iniciando novas threads

Em Java, uma thread representa: Um objeto da classe java.lang.Thread

Uma thread de execução, que tem a sua própria pilha de chamadas (call stack)

Uma thread pode ser definida de duas formas: Estendendo a classe java.lang.Thread

Implementando a interface Runnable

Page 366: 57547801-Scjp

366

Iniciando novas threads

Estendendo a classe java.lang.Thread

class MyThread extends Thread {

public void run() {

System.out.println("job rodando na thread MyThread");

}

}

Page 367: 57547801-Scjp

367

Iniciando novas threads

Implementando a interface Runnableclass MyRunnable implements Runnable {

public void run() {

System.out.println("job executando");

}

}

Page 368: 57547801-Scjp

368

Iniciando novas threads

A tarefa que a thread deve executar deve estar codificada no método run()

A execução da thread será feita usando uma pilha de chamadas especificamente designada a ela

Page 369: 57547801-Scjp

369

Iniciando novas threads

Instanciando uma thread

Forma 1MyThread t = new MyThread();

Forma 2MyRunnable r = new MyRunnable();// onde e’ defindo o

job

Thread t = new Thread (r); // onde o job e’ executado

Page 370: 57547801-Scjp

370

Iniciando novas threads

Após a criação do objeto Thread na heap, ainda não existe uma thread de execução (nova pilha de chamadas)

Uma thread construída mas não iniciada está no estado NEW

Page 371: 57547801-Scjp

371

Iniciando novas threads

Iniciando uma thread

MyRunnable r = new MyRunnable();Thread t = new Thread (r);t.start();

Quando o método start() é chamado:1. Uma nova thread de execução é iniciada (com uma nova pilha

de chamadas)2. A thread sai do estado NEW e vai para o estado RUNNABLE3. Quando a thread tiver a chance de executar, o método run() será

executado (vai para o estado RUNNING)

Page 372: 57547801-Scjp

372

Iniciando novas threads

Page 373: 57547801-Scjp

373

Iniciando novas threads

Não há garantia que as threads executarão na mesma ordem em que foram iniciadas (ordem de chamada dos métodos start())

Não há garantia que uma vez que uma thread comece a executar, ela continuará executando sem interrupções até que chegue ao fim

A única garantia dada pela JVM é que todas as threadsserão iniciadas e executarão o seu job por completo

Page 374: 57547801-Scjp

374

Iniciando novas threads

O Escalonador da JVM (“Thread Scheduler”) É papel do escalonador decidir qual deve ser a thread,

dentre todas as disponíveis, que deve estar em execução

Quando uma thread inicia sua execução, a outra threadque estava executando volta ao pool de threads(“runnable pool”)

Uma thread disponível para execução é uma thread que está no estado RUNNABLE

A ordem na qual as threads são escolhidas para execução não é garantida

Page 375: 57547801-Scjp

375

Diagrama de estados

Page 376: 57547801-Scjp

376

Diagrama de estados

O estado NEW A instância da Thread foi criada, mas o método start()

ainda não foi chamado

Ainda não há uma thread de execução!

Page 377: 57547801-Scjp

377

Diagrama de estados

O estado RUNNABLE A thread está disponível para execução (não está

executando)

A thread entra nesse estado pela primeira vez assim que o método start() é chamado

A thread retorna para RUNNABLE depois de executar a sua “vez” ou então depois de voltar do estadoWAITING/BLOCKING

Page 378: 57547801-Scjp

378

Diagrama de estados

O estado RUNNING A thread foi selecionada pelo escalonador para ser

executada

Há somente um modo de uma thread entrar no estadoRUNNING: sendo escolhida pelo escalonador

Page 379: 57547801-Scjp

379

Diagrama de estados

O estado WAITING/BLOCKING/SLEEPING A thread ainda está “viva”, porém indisponível para

execução

A thread nesse estado pode estar esperando pela liberação de algum recursO, hibernando (sleeping) ou então aguardando um evento gerado por outra thread(mecanismo de wait/notify)

Page 380: 57547801-Scjp

380

Diagrama de estados

estado DEAD A thread vai para o estado DEAD quando seu método run()

chega ao fim O objeto Thread ainda existirá, mas a thread de execução

não A thread que deixou de ser thread não pode ser novamente

iniciada (uma nova chamada a start() causa runtimeexception)

Page 381: 57547801-Scjp

381

Diagrama de estados

Transição para SLEEPING O método estático sleep(), da classe Thread, provoca uma pausa

na execução da thread (manda a thread ir “dormir”)

A thread após acordar retorna para RUNNABLE, ou seja, volta ao pool de threads disponíveis para execução

Exemplo:try {

Thread.sleep(5*60*1000); // Dorme por 5 minutos

} catch (InterruptedException ex) { }

Page 382: 57547801-Scjp

382

Diagrama de estados

Transição para RUNNABLE com o método yield() Faz a thread atualmente em execução voltar ao pool (estado

RUNNABLE) para permitir que outras threads possam executar

A thread pode não sair do estado RUNNING Se a thread sair do estado RUNNING, ela pode ser

escolhida pelo escalonador para retornar à execução

Page 383: 57547801-Scjp

383

Diagrama de estados

Transição para BLOCKING com o método join() Faz a thread atualmente em execução bloquear até que outra

thread tenha finalizado a sua execução

Exemplo:Thread t = new Thread();

t.start();

t.join();

A thread que executar o código acima estará dizendo “t deve terminar antes que eu possa executar novamente”

Page 384: 57547801-Scjp

384

Diagrama de estados

Uma thread sai do estado RUNNING quando: O seu método run() termina

É chamado o método wait() em um objeto

A thread não consegue obter o lock de um objeto

O escalonador decide interromper a execução da thread e deixar outra thread executar

Page 385: 57547801-Scjp

385

Sincronização

Todo objeto em Java tem um lock Quando uma thread invoca um método synchronized em um

objeto, ela obtém o lock do objeto Como só há um lock por objeto, se uma thread obteve o lock,

nenhuma outra poderá obter até que a thread detentora do locko libere.

Somente a thread com o lock pode executar código synchronized.

A liberação do lock ocorre quando o método synchronizedchega ao fim

Page 386: 57547801-Scjp

386

Sincronização

É possível sincronizar um método inteiro ou apenas um bloco de código

Exemplopublic synchronized void doStuff() {

System.out.println("synchronized");}// Forma equivalentepublic void doStuff() {

synchronized(this) {System.out.println("synchronized");}

}

Variáveis ou classes não podem ser declaradas com a palavra reservada synchronized

Page 387: 57547801-Scjp

387

Sincronização

Exemplo: “Condição de corrida”class ContaCorrente {private int saldo = 50;

public int getSaldo() {return saldo;

}public void realizaSaque(int valor) {

saldo = saldo - valor;}

}

Uma conta corrente possui dois correntistas: Fred e Lucy Eles querem realizar saques de $10,00, porém o saldo nunca

pode ficar negativo

Page 388: 57547801-Scjp

388

Sincronização

Exemplo: “Condição de corrida”public class AccountDanger implements

Runnable {private ContaCorrente cc = new

ContaCorrente();public static void main (String []

args) {AccountDanger r = new

AccountDanger();Thread one = new Thread(r);Thread two = new Thread(r);one.setName("Fred");

two.setName("Lucy");one.start(); two.start();

}public void run() {

for (int x = 0; x < 5; x++) {saca(10); // faz um saque de

$10,00if (cc.getSaldo() < 0) {System.out.println("limite

estourou!");}} }

private void saca(int val) {if (cc.getSaldo() >= val) {

System.out.println(Thread.currentThread().getName() + " vai fazer um saque");try { Thread.sleep(500);} catch(InterruptedException ex) { }

cc.realizaSaque(val);System.out.println(Thread.cu

rrentThread().getName() + " completou o saque");}else

System.out.println("Conta sem saldo para " +Thread.currentThread().getName() + " sacar: " +cc.getSaldo());}

Page 389: 57547801-Scjp

389

Sincronização

Se a thread está tentando executar um método synchronized mas o lock do objeto não está mais disponível, a thread fica bloqueada

A thread fica nesse estado até que o lock do objeto em questão seja liberado, quando então ela retornará ao estado RUNNABLE

Page 390: 57547801-Scjp

390

Comunicação entre threads

É realizada utilizando os métodos da classe Object: wait() notify() notifyAll()

Esses métodos têm que ser chamados a partir de um contexto sincronizado (método ou bloco synchronized)

Uma thread não pode invocar os métodos wait() ou notify() em um objeto sem antes ter obtido o seu lock

Page 391: 57547801-Scjp

391

Comunicação entre threads

Todo objeto em Java tem uma lista de threads que estão esperando por uma notificação do objeto

Uma thread entra nessa lista ao chamar o método wait() no objeto

Uma vez na lista, a thread não executa mais nenhuma instrução até que o objeto alvo chame o método notify()

Page 392: 57547801-Scjp

392

Comunicação entre threads

Chamando o método wait()

synchronized(outroObjeto) { // obtem o lock em outroObjetotry {

outroObjeto.wait();// a thread libera o lock e espera// apos ser notificada, retoma a execucao aqui

} catch(InterruptedException e){}}

Após a chamada a wait() no objeto alvo, a thread libera o lockque tinha obtido, sai do estado RUNNING e vai para o estado WAITING

Quando uma thread chama sleep() o lock não é liberado! O mesmo se aplica aos métodos yield() e join()

Page 393: 57547801-Scjp

393

Comunicação entre threads

Chamando o método notify()synchronized(this) {notify();}

Quando notify() for chamado em outroObjeto, a thread que estava aguardando ficará novamente disponível para execução, ou seja, sai do estado WAITING e vai para o estado RUNNABLE

Se várias threads estão esperando na lista de outroObjeto, apenas uma será escolhida, e a ordem de seleção não égarantida

Page 394: 57547801-Scjp

394

Comunicação entre threads

Utilizando notifyAll() O método notifyAll() permite que todas as threads

esperando na lista do objeto retornem ao estado RUNNABLE

Todas as threads serão notificadas e começarão a competir pela obtenção do lock do objeto

Page 395: 57547801-Scjp

395

Comunicação entre threads

class Reader extends Thread {Calculator c;public Reader(Calculator calc) { c = calc; }public void run() {synchronized(c) {try {

c.wait();} catch (InterruptedException e) {}

System.out.println("Total = " + c.total);}}public static void main(String [] args) {

Calculator calculator = new Calculator();new Reader(calculator).start(); new Reader(calculator).start();new Reader(calculator).start();calculator.start();

}}class Calculator extends Thread {

int total;public void run() {synchronized(this) {for(int i=0;i<100;i++) total += i;System.out.println("Fim do calculo");notifyAll();System.out.println("Notificacoes enviadas");

}}}

Page 396: 57547801-Scjp

396

Objetivos

Utilizar classes internas

Page 397: 57547801-Scjp

397

Classes Internas

Classes internas padrão

Classes internas locais a métodos (method-local)

Classes internas anônimas (anonymous)

Classes internas aninhadas estáticas (static nestedclasses)

Page 398: 57547801-Scjp

398

Classes Internas “padrão”

Uma classe interna é uma classe declarada dentro de outra classe

Uma instância da classe interna tem acesso a todos os atributos e métodos da classe que a contém, mesmo aqueles definidos como private

Sintaxe básicaclass MyOuter {private int x = 7;// inner class

class MyInner {public void seeOuter() {System.out.println("Outer x is " + x);}

} // fecha inner class} // fecha outer class

Page 399: 57547801-Scjp

399

Classes Internas “padrão”

Instanciando uma classe interna de dentro da classe que a contém

class MyOuter {private int x = 7;public void makeInner() {MyInner in = new MyInner();in.seeOuter();}

class MyInner {public void seeOuter() {System.out.println("Outer x is " + x);}

}}

Page 400: 57547801-Scjp

400

Classes Internas “padrão”

Instanciando uma classe interna de fora da classe que a contém

public static void main(String[] args) {MyOuter mo = new MyOuter();MyOuter.MyInner inner = mo.new MyInner();inner.seeOuter();

}// Forma equivalentepublic static void main(String[] args) {

MyOuter.MyInner inner = new MyOuter().new MyInner();inner.seeOuter();

}

Page 401: 57547801-Scjp

401

Classes Internas “padrão”

Uma classe interna padrão faz parte da classe que a contém, da mesma forma que os atributos e métodos da classe

Os seguintes modificadores podem ser aplicados às classes internas: final abstract public private protected static strictfp

Page 402: 57547801-Scjp

402

Classe interna local de método

É declarada dentro de um método Sintaxe básicaclass MyOuter2 {

private String x = "Outer2";void doStuff() {

class MyInner {public void seeOuter() {System.out.println("Outer x is " + x);} // fecha metodo da inner class

} // fecha declaracao da inner classMyInner mi = new MyInner(); // Deve vir apos a classemi.seeOuter();} // fecha metodo doStuff() da outer class

} // fecha outer class

Page 403: 57547801-Scjp

403

Classe interna local de método

A classe interna não pode ser instanciada em nenhum outro bloco de código a não ser no próprio método na qual foi declarada

Somente pode acessar parâmetros ou variáveis locais declarados como final

Os únicos modificadores permitidos são abstract e final

Page 404: 57547801-Scjp

404

Classe interna anônima

Exemplosclass Popcorn {

public void pop() { System.out.println("popcorn");}}class Food {

Popcorn p = new Popcorn() { // declara uma classe que e’ subclasse dePopcornpublic void pop() {

System.out.println("anonymous popcorn");}

};}interface Cookable { public void cook(); }class Food {

Cookable c = new Cookable() { // declara uma classe que implementa a interfacepublic void cook() {

System.out.println("anonymous cookable implementer");}

};}

Page 405: 57547801-Scjp

405

Classe interna anônima

Classes internas anônima definida no argumento de um método

class MyWonderfulClass {void go() {Bar b = new Bar();

b.doStuff(new Foo() {public void foof() {System.out.println("foofy");} // fim do metodo foof}); // fim da inner class e da chamada a b.doStuff()

} // fim do go()} // fim da classe

interface Foo {void foof();}class Bar {void doStuff(Foo f) { }}

Page 406: 57547801-Scjp

406

Classe interna Estática

É uma classe interna declarada com o modificador static

A classe interna estática não tem nenhum relacionamento com as instâncias da classe que a contém

O modificador static indica que a classe internapode ser acessada por outras classes, sem que seja necessária a criação de uma instância da classe que a contém

Page 407: 57547801-Scjp

407

Classe interna Estática

Exemploclass BigOuter {

static class Nest {void go() { System.out.println("hi"); } }

}class Broom {

static class B2 {void goB2() { System.out.println("hi2"); } }

public static void main(String[] args) {BigOuter.Nest n = new BigOuter.Nest();n.go();B2 b2 = new B2();b2.goB2();

}}