As 3 frases essenciais do documento são:
1) O documento fornece resumos e anotações importantes sobre os fundamentos da certificação SCJP 5.0, incluindo detalhes sobre variáveis, operadores, estruturas de controle, classes e interfaces.
2) São destacados pontos de atenção sobre inicialização e escopo de variáveis, operadores lógicos e de atribuição, encapsulamento, herança, polimorfismo e coleta de lixo.
3) Também são abordados conceitos-chave como override
Programação Orientada a Objetos - Conceitos básicos da linguagem JAVA
Resumo Anotacoes Certificacao SCJP 5
1. Resumo_Certificacao_SCJP_5.txt
===============================================================================
Resumo Anotações para Certificação SCJP 5.0
Autor:
Gilberto Augusto Holms
gibaholms85@gmail.com
@gibaholms
http://gibaholms.wordpress.com/
===============================================================================
===============================================================================
FUNDAMENTOS
===============================================================================
- Decorar todas as palavras reservadas
- Ordem obrigatória: package, imports e classes (sendo apenas 1 publica)
- Arquivo .java em branco ou sem classes também é válido
- Método main - assinaturas válidas:
public static void main( String args[] ) {}
final public static void main( String args[] ) {}
- Decorar ranges e tamanho-bytes de todas as variaveis primitivas
- Caracteres especiais: "Big Farms Need Red Tractors" (BFNRT)
- Operações com inteiros sempre resulta int (exceto se tiver long)
- Operações que envolvem um tipo maior, resultam num tipo igual o do maior
(float + double = double)
- Constantes (final) não podem ter contas com variáveis
- Cuidado! Não existe cast de String (inclusive pois ela é final e
não possui herdeiras)
String s1 = (String)'A'; //ERRO DE COMPILAÇÂO
- Não confundir [] com () na declaração de vetores
- Cuidado! Vetor pode ter índice acessado apenas com variáveis promovíveis
para int ou constantes
- Atribuir valores entre chaves em vetores é permitido apenas na inicialização
int vetor[] = new int[3];
vetor = {1, 2, 3}; //ERRO DE COMPILAÇÂO !!
vetor = new int[] {1, 2, 3, 4, 5}; //isso poderia, redefiniria o vetor
- Ex 1.12 - Cuidado! Ao igualar vetores, sempre verificar se as dimensões
se completam:
int v1[][] = new int [2][3];
int v2 [][][][] = new int[2][2][2][2];
v2[0][1][1] = v1; //ERRO DE COMPILAÇÂO !!
v2[0][1][1] = v1[0]; //OK!
v2[0][1] = v1; //OK!
- Ex 1.16 - Cuidado!
String [][]x = new String [2][];
System.out.println( x[1][0] );
//ERRO DE EXECUÇÃO !! NullPointerException
- Ex 1.18 - Cuidado! Sempre que chamar o vetor args [] do método main com
seus índices explicitos, ver se o numero de argumentos digitados não gera
um ArrayIndexOutOfBoundsException:
String s1 = args[0];
String s2 = args[1];
String s3 = args[2];
Página 1
2. Resumo_Certificacao_SCJP_5.txt
//Se tivesse só 2 argumentos, aqui geraria ERRO DE EXECUÇÃO
- Ex 1.20 ver a formação de um vetor String X[] = new String [2][2]
- Ex 1.43 - Cuidado!
int x = 10, y;
if (x < 10) y = 1;
if (x >= 10) y = 2;
System.out.println( y ); //ERRO DE COMPILAÇÃO !!
//Variável local foi lida sem ser inicializada
//Obs.: deu erro porque poderia haver código entre os dois if
//se fosse driblado no if com else, aí inicializaria com certeza
- Pode inicializar variáveis deste modo:
i = x = j = 1; //neste caso, todas valerão 1
//Obs.: se fosse utilizar +=, a variável que recebe precisaria
//ter sido inicializada antes
- Ex 1.60 - Cuidado!
public static void main(String[] args) {
int i[] = {1};
change(i);
System.out.println(i[0]); //IMPRIME 1
}
static void change(int i[]) {
int j[] = {2};
i = j;
}
- Ex 1.20 - Cuidado!
String x[][] = new String[2][2];
String y[] = new String[15];
x[0] = y;
System.out.println(x[0].length); //IMPRIME 15
===============================================================================
VARIÁVEIS
===============================================================================
- Intervalo das variáveis
- Operações com inteiros sempre resulta int
- Promoção de variáveis (casting)
- Variaveis locais precisam ser inicializadas (cuidado com if sem else)
- Cuidado com variáveis de escopo de bloco de código sendo usadas depois
do bloco
- Cuidado com variavel declarada no if e usada no else (analogo para
outros blocos)
- Var de referencia locais também precisam ser inicializadas (apontar um
objeto ou null)
- Cuidado com sombreamento: sempre vale a local
- Não pode sombrear variavel local com variavel de bloco
- Declarando e inicializando arrays:
int x[] = new int[3];
int x[] = {1,2,3}
int x[] = new int[] {1,2,3}
- Não confundir propriedade length do vetor com método length() da String
- Blocos de inicialização
Página 2
3. Resumo_Certificacao_SCJP_5.txt
. A ordem em que aparece faz diferença (executados de cima pra baixo)
. São estaticos (1 vez) ou instancia (1 vez por operador new)
. Executados antes do construtor
. Ordem de inicialização: bloco estatico pai, bloco estatico filho,
bloco instacia pai, construtor pai, bloco instancia filho, construtor filho
- Bloco de inicialização estático: executado quando a classe é carregada
(quando o primeiro objeto da classe é criado)
static { //comandos }
- Bloco de inicialização de instância: executado quando a classe é instanciada
{ //comandos }
===============================================================================
MODIFICADORES
===============================================================================
- Não pode abstract private, abstract final, abstract static
- Pode abstract protected
- Pode argumento final (não pode ser modificado dentro do método)
- Pode variavel de referencia final (nao pode mudar o objeto a qual aponta)
- Cuidado com protected (acesso por herança = sim VS. acesso
por instancia = não) - depois se torna private para outras classes que
instanciem a subclasse pelo pacote da subclasse, mas normal se for pelo
pacote da superclasse
===============================================================================
OPERADORES
===============================================================================
- Divisão por zero (inteiros)
- Comparação é apenas com booleanos
- Cuidado com Inteligente (&& , ||) vs. Burro (& , |)
- Cuidado com pós-incremento e pré-incremento
- Deslocamento de bits
<< Desloca para esquerda completando com zero
>> Desloca para direita, completando com o que estava antes
>>> Desloca para direita, completando com zero
Manipulando Binarios Negativos:
. Inverte tudo
. Soma 1
. Faz a conta especificada
. Se continuar negativo (mais significativo é 1), inverte tudo
e soma 1
. Se tornar-se positivo (mais significativo é 0), já é o valor
- Operador ternario condicional sempre precisa os tres pedaços
- Operadores atribuição fazem conversão implícita
byte b = 3;
b += 7; //OK
b = b + 7; //ERRO - precisa de (int)(b + 7)
- Atenção:
String x = null;
x instanceof String; //é sempre false
null instanceof String; //é sempre false
- Cuidado com concatenação misturada com soma (precedencia é da esquerda
para direita)
Página 3
4. Resumo_Certificacao_SCJP_5.txt
- Cuidado com 5 && 6 (não pode - 5 & 6 pode)
===============================================================================
ESTRUTURAS DE CONTROLE
===============================================================================
- Switch só pode verificar variáveis promovíveis para int
- Cases do switch podem apenas valores constantes inteiros ou enum
(nunca variáveis)
- Variáveis inicializadas no for servem apenas para o for
- Pode ter um for vazio (;;;)
- Break pode apenas em switch e nas estruturas de repetição (sai da estrutura)
- Continue pode apenas nas estruturas de repetição (prox. iteração)
- Em caso de rótulos no break ou continue, vale e estrutura rotulada (cuidado
com rótulos perdidos no meio do código - vale somente para os laços)
===============================================================================
STRINGS E STRINGBUFFER
===============================================================================
- Cuidado:
String tem método lenght(), portanto com os parênteses
Vetor tem propriedade lenght, portanto sem os parênteses
- String são objetos, portanto imutáveis
- Quando "mudamos" uma string, na verdade criamos um objeto novo e
redirecionamos a referência a ele, onde o anterior irá pra coleta de lixo
- Exemplo:
String s1 = "spring"; //um objeto - uma referência
String s2 = s1 + " summer"; //três objetos
//(spring, summer e spring summer) - duas referências
//(summer é perdido)
s1.concat(" fall");
System.out.println(s1); //imprime spring
System.out.println( s1.concat(" fall") ); //imprime spring fall
s1 = s1.concat("fall");
System.out.println(s1); //imprime spring fall
- Pool de Strings: área reservada na memória onde a JVM guarda todas as
strings literais. Quando é criada uma string literal, a JVM analisa o pool
e observa se já tem uma idêntica. Se já tiver, ao invés de criar outra,
ele só duplica sua referência usando a variável definida.
//supondo que aqui não há nenhuma string no pool
String s = "abc"; //cria um objeto string abc, inserido-o no pool
//e s o referenciará
//supondo que aqui não há nenhuma string no pool
String s = new String("abc");
//cria dois objetos string abc, um na memória
//comum (operador new) e um no pool ("abc"), e s referenciará o da
//memória, que por sua vez refenciará o do pool
- Métodos interessantes
String y;
String x = "0123456789";
y = x.substring(5); //começa no índice 5 e vai até o fim -> 56789
Página 4
5. Resumo_Certificacao_SCJP_5.txt
y = x.substring(5, 8);
//começa no índice 5, pegando 8-5 = 3 caracteres -> 567
String w = " giba holms ";
w = w.trim(w); //remove espaços -> gibaholms
- StringBuffer: trabalha a String sobre ela mesma, e não fica perdendo
espaço gravando no pool:
StruingBuffer sb = new StringBuffer("abc");
sb.append("def");
System.out.println(sb); //imprime -> abcdef
===============================================================================
CLASSES E OBJETOS
===============================================================================
- Para acessar estaticos, usar o nome da classe (ou um objeto já instanciado)
- Não pode usar operador this dentro de métodos estáticos
- Para chamar outros construtores, pode usar this() ou super() apenas na
primeira linha de um constutor
- Um objeto que referencia outro da mesma classe, pode acessar os
membros private !!!!
- "É Um" VS. "Tem Um"
. É Um = extends e implements
. Tem Um = variável de referência
- Encapsulamento - benefícios:
. Clareza do código
. Possibilidade de adicionar novas funcionalidades e validações
. Facilidade de manutenção
- Encapsulamento - não benefícios
. Eficiência / performance do código
- Herança
. É-um = abaixo na relação de herança
. Tem-Um = operador new
. Override
. Overload
. Pode override de variável
- Acoplamento: baixo = classes fornecem apenas serviços, independentemente da
implementação
- Coesão: alta = classe que faz uma tarefa bem específica
===============================================================================
OVERRIDE vs. OVERLOAD
===============================================================================
- Override:
. Não pode mudar tipos do parâmetro nem retorno
. Exceções: podem ser reduzidas ou eliminadas (se não forem
verificadas, não importa)
. Acesso: não pode reduzir acesso
- Overload
. Deve mudar tipos do parâmetro
. Parametros apenas em ordem diferente já é overload
. Por ser um método diferente, não possui outras restrições
. Para parâmetro passado como objeto, o tipo da referência que manda
. Para parâmetros com overload, se a JVM não encontrar correspondencia
exata de tipo, ela usa o método com o proximo mais amplo argumento
Página 5
6. Resumo_Certificacao_SCJP_5.txt
===============================================================================
CONSTRUTORES
===============================================================================
- Cuidado com método com retorno, disfarçado de construtor
- Construtor private faz com que a classe só possa ser instanciada dentro dela
mesma
- Pode contrutor protected, porém também limita quem pode instanciar
- Não pode fazer uma chamada ao contrutor de dentro de um método
- Cuidado com o construtor declarado com argumentos, que inibe o padrão
(a não ser que seja explicitamente declarado)
- Cuidado com construtor da superclasse com argumentos (problema acima)
===============================================================================
INTERFACES
===============================================================================
- Métodos são public abstract
- Atributos são public static final (ou seja, são CONSTANTES - não podem
alterar seu valor durante o codigo)
- Não pode ter métodos static
- Não pode ter métodos final, native, strictfp ou synchronized
- Métodos não podem ser declarados com private ou protected
- Pode extends interface (ou mais de uma interface)
- Não pode implements nada
- Pode ser declarada como public abstract interface
- Como classes, pode ser public ou default
- Cuidado com classe concreta que não implementa método abstrato da interface
quando uma superclasse dela já o fez (válido)
===============================================================================
CLASSES ABSTRATAS
===============================================================================
- Apesar de não serem instanciadas, podem ter construtor (executado quando
uma herdeira é instanciada)
- Apenas um método abstract contamina toda a classe como abstract
- Classe abstrata herdando de classe abstrata não precisa implementar métodos
- Cuidado com classe concreta que não implementa método abstrato da classe
abstrata quando uma superclasse dela já o fez (válido)
===============================================================================
POLIMORFISMO
===============================================================================
- Cuidado com erros de downcasting (uso do instanceof)
- Operador instanceof = É-UM
- Cuidado com ClassCastException - é erro de runtime (atenção para se uso
com operadores lógicos de abreviação)
===============================================================================
MEMBROS ESTATICOS
Página 6
7. Resumo_Certificacao_SCJP_5.txt
===============================================================================
- Método estatic só pode acessar membros também static
- Método Static pode ser "redefinido" (um pouco diferente de sobrescrito,
pois não existe super.metodo )
===============================================================================
COLETA DE LIXO
===============================================================================
- System.gc()
- Nunca é garantida a execução
- Pode executar o método finalize() apenas uma vez, e não garante quando
- Objeto elegível = referência null
- Cuidado com "ilhas de isolamento" - também ficam elegíveis
===============================================================================
CLASSES WRAPPER
===============================================================================
- Todas exceto Character tem construtor com argumentos: String e seu literal
primitivo
- Character aceita apenas o seu literal primitivo
- Não possuem construtor padrão ()
- Método valueOf( String, base ) - estático - retorna um objeto wrapper do
objeto utilizado
- Método xxxValue() - retorna o tipo primitivo do wrapper
- Método parseXXX(String) - estático - retorna o primitivo da String no
parâmetro
- Todos têm valueOf() exceto Character
- Todos têm parseXXX(String) exceto Character e Boolean
- Todos têm xxxValue() exceto Character e Boolean
- Apenas Integer e Long possuem toXXXString( primitivo ) - estático - retorna
string com base XXX
- Método equals() em wrapper: são iguais se tiverem mesmo tipo e mesmo valor
- Classes wrapper não tem relação herança, ou seja, "Short NÃO é-um Integer"
- Todas as classes Wrapper tem como PAI comum a interface Number
- Observações
Byte n1 = new Byte(2); //ERRO !!!!
Byte n1 = new Byte((byte)2); //OK
Byte n1 = new Byte("2"); //OK
Number n1 = new Byte("2"); //OK
===============================================================================
EXCEÇÕES
===============================================================================
- Posso pegar (catch) toda a hierarquia de erros (Throwable, Error,
Exception ou RuntimeError), obedecendo o polimorfismo
- O erro é passado de método para método até achar um catch, ou chegar no fim
Página 7
8. Resumo_Certificacao_SCJP_5.txt
do programa. Ele vai finalizando os métodos na ordem da pilha
- Pode-se fazer novas excessões extendendo as classes de erro
- Quando se lança uma Exception ou qualquer subclasse dela (exceto
RuntimeException), é OBRIGATÓRIO capturá-la com o catch, ao menos que o método
contenha Trhows Exception na assinatura
- Error e RuntimeException não são obrigatórios o seu catch
- Mesmo que o método não lance erros, se tiver throws Exception na assinatura,
só pode ser chamado dentro de um try catch
- Qualquer comando abaixo de um Throw, é erro de compilação
- Na assinatura da classe, só tem sentido utilizar "Throws Exception", que serve
para repassar o tratamento da Exception (que seria obrigatório) para o método
seguinte na pilha (então será obrigatório neste método)
- try precisa estar colado com um catch ou um finally. Também não pode catch nem
finally voando.
- Cuidado com um metodo que lanca Exception dentro de um finally. Ele precisa
ser tratado também
- É erro de compilação dois catch capturando a mesma classe de excessão no
mesmo try
- Não pode um catch mais abrangente em cima de um menos abrangente
===============================================================================
ASSERTIVAS
===============================================================================
- assert(condição):"Descrição de debug";
- Só compilando com -source 1.3 pode usar a palavra assert como identificador
- Uso inapropriado de assertivas:
. Verificar argumento de método público
. Verificar argumento da linha de comando
. Verificar default de switch
. Chamar um método dentro dela
===============================================================================
CLASSES INTERNAS
===============================================================================
- Tipos: comum, local de método, anônima e estatica
- Atenção com modificadores de acesso. Para ser acessada externamente, precisa
ser visivel tanto a externa quanto a interna
- Comum:
. Instancia na mesma classe:
Interna i1 = new Interna(); //normal
. Instancia por outra classe:
Externa e1 = new Externa();
Externa.Interna i1 = e1.new Interna();
//ou...
Externa.Interna i2 = new Externa().new Interna();
. Para instanciar, precisa de uma instancia da externa
. Portanto, não pode ser usada em método estático da externa
Página 8
9. Resumo_Certificacao_SCJP_5.txt
. Sombreamento de variáveis:
Externa.this.x; //externa
this.x; //interna
x; //local do metodo
- Local de Método:
. Só pode ser instanciada dentro do método que a contém, e depois de
sua definição (abaixo dela)
. Só pode utilizar variáveis locais do método que a contém se forem
"final"
. Pode utilizar as variáveis de instancia da classe externa total
. Se o método for estático, só poderá acessar membros estáticos da
classe externa
. Só pode ser abstract ou final
- Anonimas - herdando de classe
class Popcorn { }
Popcorn p = new Popcorn() {
//classe herdeira anonima
};
. Isso acima é uma classe anônima herdeira (subclasse) de uma Popcorn
já existente
. Valem as regras da herança e do polimorfismo
. Cuidado com a falta do ponto-e-virgula (;) no final
- Anonimas - implementando interface
interface Cookable { public void cook(); }
Cookable c = new Cookable() {
public void cook() { //implementação
}
};
. Modo curioso de se "instanciar uma interface". Na verdade estamos
criando uma classe interna anônima que implementa ela
Runnable r = new Runnable(); //ERRADOOOOOOOOOOo
Runnable r = new Runnable() { public void run() {} }; //CORRETO
. Cuidado com a falta do ponto-e-virgula (;) no final
- Anonimas - em argumento
interface Cookable { public void cook(); }
class Kitchen {
public void cook(Cookable c) { }
}
public class Argumento {
public static void main( String [] args ) {
Kitchen k1 = new Kitchen();
k1.cook( new Cookable() {
public void cook() {}
}
);
}
Página 9
10. Resumo_Certificacao_SCJP_5.txt
}
. Cuidado para não esquecer o parênteses ")" e o ponto-e-vírgula ";"
no final
- Classes Internas Estáticas
. É um "membro estático" da classe externa
. Instancia na mesma classe:
InternaEstatica ie1 = new InternaEstatica(); //normal
. Instancia por outra classe:
Externa.InternaEstatica ie1 = new Externa.InternaEstatica();
. Logicamente não pode acessas membros não-static da classe externa
. Pode ter membros comuns dentro dela, como qualquer outra
===============================================================================
COLEÇÕES
===============================================================================
- Se sobrescrever "public boolean equals(Object o)", precisa sobrescrever
"public int hashCode()"
- Interface Collection - possui as interfaces derivadas Set, List e Queue
- Interface Map não pertence à interface Collection
- Classe java.util.Collections - possui métodos utilitários static para serem
usados nas coleções
- Não confundir Collections com Collection
- Ordenado: armazenados numa ordem específica
- Classificado: assumem sua ordenação de acordo com uma regra específica
(ex. strings em ordem alfabética)
- Interface LIST
. Permite duplicatas
. Funciona em função de um índice, como um vetor
. Ordenada pelo índice
. ArrayList: ordenado pelo índice
. Vector: é um ArrayList sincronizado
. LinkedList: ordenado por encadeamento (ordem de inserção)
- Interface SET
. Não permite duplicatas
. Depende da implementação do método equals()
. HashSet: não-classificado e não-ordenado
. LinkedHashSet: ordenado por encadeamento (ordem de inserção)
. TreeSet: ordenado e classificado pela ordem natural dos elementos
- Interface MAP
. Duplas chave/valor - tabela de hash
. A chave não pode ser repetida
. Permite chave null
. Depende da implementação do método equals()
. HashMap: não-classificado e não-ordenado
. Hashtable: é um HashMap sincronizado
. LinkedHashMap: ordenado por encadeamento (ordem de inserção)
. TreeMap: ordenado e classificado pela ordem natural dos elementos
===============================================================================
Página 10
11. Resumo_Certificacao_SCJP_5.txt
THREADS
===============================================================================
- Só vale extender Thread e instanciar normal, ou implementar Runnable e enviar
como construtor para uma classe Thread
- Assinatura válida:
public void run() {}
public synchronized void run() {} //porém sincroniza apenas
//uma instância
- Chamar run() executa na pilha atual. Para ser Thread, precisa chamar start()
- Cuidado! Chamar start() sempre numa instância de Thread, não de Runnable
- Thread.currentThread() retorna uma instância ao Thread atual. É STATIC
- É erro de execução chamar o método start() mais de uma vez na mesma
referência. (IllegalThreadStateException)
- Métodos que lançam excessão verificada:
Thread.sleep()
Thread.sleep(long mili)
join()
join(long mili)
wait() - é de Object
wait(long mili) - é de Object
- sleep() força o Thread atual para estado de suspensão. Ele mantém seus
bloqueios. É STATIC
- Prioridade padrão é igual a prioridade do Thread que o criou
- yield() faz o Thread atual voltar ao pool dando chance a outro de mesma
prioridade (não garante nada) É STATIC
- join() = "me anexe ao final de", ou seja, só executa quando o expecificado
terminar
- Modificador synchronized = só para métodos. Impede que dois Threads acessem
o método simultaneamente, o que corromperia variáveis de instância. Bloqueia
o objeto atual. Outro Thread só poderia acessar quando o bloqueio for
liberado (fim do método sincronizado)
- synchonized é importante apenas para Threads que utilizam mesmas instâncias
de objetos
- Bloco synchronized = qualquer bloco. Bloqueia o objeto entre parênteses
synchronized(this) { }
- synchronized X static synchronized
Página 11