Inicial > programação > 50 dicas práticas para o exame OCJP Java 6

50 dicas práticas para o exame OCJP Java 6

Motivado por ter passado no exame da SCJP recentemente, publico abaixo 50 dicas práticas para o exame da versão 6. Elas foram retiradas e adaptadas do livro  Certificação SUN para Programador Java 6, de Kathy Sierra e Bert Bates, adicionadas em muitos casos de exemplos e comentários úteis.

    1. Saiba tudo sobre controle de acesso para o exame. Haverá uma boa quantidade de perguntas para as quais você deverá usar o seu conhecimento sobre o assunto. Quando vir uma questão com lógica complexa, certifique-se de olhar os modificadores de acesso primeiro;
    2. Procure questões com uma declaração de método que termine com ponto-e-vírgula em vez de chaves. Se o método estiver em uma classe – e não em uma interface -, então tanto o método como a classe devem ser marcados como abstract;
    3. Quando pensar em acesso padrão (default), pense em restrições de pacote, sem exceções. Mas quando pensar em protected, pense em pacote + filhos;
    4. Procure por classes concretas que não forneçam implementações para métodos abstratos da superclasse;
    5. Enums fora de uma classe só podem ser declarados com acesso public ou default, assim como uma classe não interna;
    6. As chamadas de métodos polimórficos se aplicam somente a métodos de instâncias;
    7. Procure classes que afirmam implementar uma interface, mas não fornecem as implementações de método corretas. A menos que a classe de implementação seja abstract, ela terá que fornecer implementações de todos os métodos definidos na interface;
    8. Lembre-se: um método static de uma classe não pode acessar um membro – método ou variável – não estático (de instância) de sua própria classe;
    9. Procure perguntas que usem números onde os booleanos seriam obrigatórios. Você pode ver uma avaliação de instrução if que use um número, como na linha a seguir:
int x = 1;
if (x) { } // Erro do compilador

    1. Tome cuidado com variáveis sombreadas e  com erros de escopo em blocos de código como switches, try-catches e loops;
    2. Lembre-se que quando duas referências apontem para o mesmo objeto, se uma delas for usada para alterá-lo, as duas saberão da alteração, porque ainda haverá somente um objeto. Mas sempre que forem feitas alterações em uma String, a VM atualizará a variável de referência para fazê-la apontar para um objeto diferente. Exemplo:
String x = "Pablo";
String y = x; // y e x referenciam o mesmo objeto String

System.out.println("y = " + y); // Imprime 'Pablo'
x = x + " Nóbrega"; // Altera somente x. Foi criado um novo objeto e a referência foi atualizada
System.out.println("y = " + y); // Continua imprimindo 'Pablo'

A saída para esse código será:
y = Pablo
y = Pablo

    1. No exame será esperado que você saiba, por exemplo, que o código abaixo produz apenas um objeto (o array atribuido a variável de referência inteiros). Nenhum objeto Integer foi realmente criado.
Integer[] inteiros = new Integer[5];
    1. As variáveis de referência wrapper podem ser null, portanto tome cuidado com algum código que pareça estar realizando operações seguras com primitivos, mas que lançam NullPointerException. Exemplo:
class TesteTempo {
   static Long tempo;

   static void calculaTempo(int parametro) {
      System.out.println(parametro + 5);
   }
   public static void main(String[] args) {
      calculaTempo(tempo); // NullPointerException. 'tempo' não foi inicializada
   }
}
    1. Nenhuma das classes wrapper pode ser ampliada de uma para outra. Por exemplo: Byte não se amplia para Short, Short não se amplia para Long, etc. O código abaixo não vai funcionar:
class TesteAmpliacao{
   void ampliar(Long parametro) {
      System.out.println(parametro);
   }

   public static void main(String[] args) {
      TesteAmpliacao teste = new TesteAmpliacao();
      teste.ampliar(new Integer(10)); // impossível ampliar de Integer para Long
   }
}
    1. Tenha em mente que uma vez que o coletor de lixo entre em ação, não há garantia de que todos os objetos não utilizados serão realmente removidos da memória;
    2. Fique atento! A parte do exame referente aos operadores e atribuições normalmente é aquela em que os candidatos conseguem menos pontos. Por isso, muita atenção nas questões que envolvem esses assuntos;
    3. Você deve compreender de forma clara como a concatenação de Strings funciona, principalmente dentro de uma instrução print. Veja o exemplo abaixo:
int b = 2;
System.out.println("" + b + 3); // Imprime '23'
System.out.println(b+3); // Imprime 5
    1. Procure questões que usem operadores de incremento e decremento em variáveis final. Obviamente que qualquer tentativa de utilizá-los nessa situação resulta em uma exceção.
    2. Os operadores && e || só funcionam com operadores booleanos. Você pode encontrar questões que usem inteiros com esses operadores (dando a impressão que estamos usando o operador bit a bit &). Exemplo:
if (5 && 6) // Erro de compilação.
    1. Retirando-se uma saída forçada (break, return, System.exit(), etc), as avaliações da expressão de iteração e, posteriormente, da expressão condicional, são sempre as duas últimas coisas a ocorrerem em um loop for.
    2. Procure códigos que invoquem métodos que declarem uma exceção, mas o método que estiver chamando não manipule ou declare a exceção verificada. Exemplo abaixo:
void aumenta() { // falta método manipular ou declarar a exceção que deveria ser lançada por realizaCalculo()
   realizaCalculo();
}

void realizaCalculo() { // falta método lançar com throws
   throw new IOException();
}
    1. Se você se deparar com a palavra expressão em uma pergunta sobre assertivas e ela não especificar se está se referindo à primeira expressão (teste booleado) ou à segunda (o valor a ser exibido no rastreamento da pilha), então assuma que sempre está se referindo ao teste booleano.
    2. Os arrays têm um atributo (não um método) chamado length. É possível que você encontre alguma pergunta que troque o atributo pelo método length(), da classe String, ou vice-versa. Exemplo:
String teste = "teste";
System.out.println(teste.length); // Erro de compilação
}
    1. Criar diretórios em Java é diferente de criar arquivos. Ao se construir um Reader ou um Writer, automaticamente um arquivo é criado, caso não exista. Porém o mesmo não ocorre com diretórios, ou seja, o diretório não será criado caso estejamos tentando escrever em um novo arquivo daquele diretório que você deseja que exista. Veja o exemplo abaixo e observe que a linha que cria o diretório está comentada:
File diretorio = new File("novoDir");
// diretorio.mkdir(); // Criação de diretório comentada
File arquivo = new File(diretorio, "meuArquivo.txt");
arquivo.createNewFile(); // Exceção por conta de o diretório não existir.
    1. Você deverá saber quais variáveis são restauradas com os valores apropriados e quais não são, quando um objeto é deserializado. Veja um exemplo:
import java.io.*;
class SuperClasseNaoSerializada {
   public static void main(String[] args) {
      Leao leao = new Leao(120, "Juba");
      System.out.println("antes de deserializar: " + leao.nome + " " + leao.tamanho);
      try {
         FileOuputStream fos = new FileOutputStream("arquivo.txt");
         ObjectOutputStream oos = new ObjectOutputStream(fos);
         oos.writeObject(leao); oos.close();
      } catch (Exception ex) { e.printStackTrace(); }

      try {
         FileInputStream fis = new FileInputStream("arquivo.txt");
         ObjectInputStream ois = new ObjectInputStream (fis);
         leao = (Leao) ois.readObject(); ois.close();
      } catch (Exception ex) { e.printStackTrace(); }

      System.out.println("depois de deserializar: " + leao.nome + " " + leao.tamanho);
   }

}
class Leao extends Animal implements Serializable {
   String nome;
   Leao(int t, String n) {
      tamanho = t; // herdado de Animal
      nome = n; // não herdado
   }
}
class Animal {
   int tamanho = 105;
}

A saída para esse código será:
antes de serializar: Juba 120
depois de deserializar: Juba 105

    1. Atenção: a contagem dos meses em um Calendar começa em 0 (zero);
    2. Os objetos DateFormat e NumberFormat podem ter os seus locais definidos somente no momento da instanciação. Cuidado com códigos que tentam modificar o local de uma instância existente. Exemplo:
class TestaLocal {
   public static void main(String[] args) {
      DateFormat df = DateFormate.getInstance();
      df.setLocale(new Locale("it", "IT"));
   }
}
    1. Metacaracteres e Strings não trabalham bem juntos. Portanto, tome cuidado com código como o abaixo, pois ele não compila:
class TestaPattern {
   public static void main(String[] args) {
      String patternInvalido= "\d"; // Pattern inválido. Não compila.
      Pattern p = Pattern.compile(patternInvalido);
   }
}
    1. Quando encontrar uma sobrescrição de equals(), hashCode() e toString() verifique se não houve uma mudança de visibilidade, pois o método deve ser public. Além disso, observe se não está sendo feita uma sobrecarga, ao invés de sobrescrita. O primeiro código abaixo, por exemplo, é inválido e o segundo é uma sobrecarga válida:
class ErroEquals {
   boolean equals(Object o) { // visibilidade default: não compila
      return false;
   }
}
class Bola {
   boolean equals(Bola bola) { // sobrecarga válida
      return true;
   }
}
    1. Na prova, tenha cuidado com a interpretação de certas questões. Não confunda, por exemplo, o uso apropriado ou correto do código de hashing, com a validade ou eficiência da solução implementada;
    2. Cuidado para não confundir as classes Collections e Collection. Collection é uma interface com as declarações de métodos comuns a várias coleções e Collections é uma classe com métodos estáticos utilitários;
    3. É importante reconhecer o que é interface e o que é classe concreta quando se trata de coleções. O código abaixo não compila porque Map é uma interface:
class TestaMap {
   public static void main(String[] args) {
      Map<String, String> mapa  = new Map<String, String>();
   }
}
    1. Entenda o funcionamento das classes Comparator e Comparable, pois elas são bastante parecidas. Analise principalmente a forma como elas trabalham e o método que utilizam para efetuar a comparação;
    2. Procure por questões no exame que tentem classificar um array de primitivos usando um Comparator, o que é inválido;
    3. Quando houver classificação de um array ou de uma coleção, os elementos contidos nesses objetos devem ser mutuamente comparáveis. Você não pode ter um Object[], colocar dentro dele um objeto Cachorro e um objeto Gato e depois efetuar uma classificação;
    4. Os erros mais comuns em busca e classificação são:
      • Procurar em um array ou coleção que não tenha sido ordenado;
      • Usar um Comparator ou só na classificação ou só na busca;
    5. Quando converter arrays em Collections, lembre-se que a atualização em um dos objetos refletirá no outro. O mesmo não vale para quando convertemos Collections em arrays. Observe o código abaixo:
class TestaColecoes {
   public static void main(String[] args) {
      String[] nomes = {"Pablo", "Nóbrega"};
      List nomesList = Arrays.asList(nomes);
      nomesList.set(1, " - Autor do Post");
      // imprime 'Pablo - Autor do Post' ao invés de 'Pablo Nóbrega'
      for (String s : nomes) {
         System.out.print(s);
      }
      System.out.println();
      List escritoresList = new ArrayList();
      escritoresList.add("Camões");
      escritoresList.add(" - Drummond");
      String[] escritoresArray = new String[escritoresList.size()];
      escritoresList.toArray(escritoresArray);
      escritoresArray[1] = " - Pessoa";

      // continua imprimindo 'Camões - Drummond'
      for (int i = 0; i < escritoresList.size(); i++) {
         System.out.print(escritoresList.get(i));
      }
   }
}

A saída para esse código será:
Pablo – Autor do Post
Camões – Drummond

    1. Certifique-se de que você entende bem a diferença entre “compilação falha”, “compila sem erros”, “compila sem avisos” e “compila com avisos”. Em genéricos e na mistura de código com e sem tipos específicos, os avisos podem fazer diferença;
    2. Ao declarar um conjunto não-genérico, o método get() irá retornar Object, portanto é necessário efetuar cast explícito. O código abaixo, por exemplo, não compila:
class TestaGenericos {
   public static void main(String[] args) {
      List teste = new ArrayList();
      teste.add(43);
      int x = teste.get(0);
      System.out.println(x);
   }
}
    1. Em genéricos, os coringas só podem ser usados para declarações de referências, ou seja, enquanto uma referência pode ser abstrata e polimórfica, o próprio objeto criado deve ser de um tipo específico. Você precisa definir o tipo quando cria o objeto usando new. O exemplo abaixo não é válido:
class TestaGenericos {
   public static void main(String[] args) {
      List<?> animais =   new ArrayList<? extends Animal>();
   }
}
    1. Classes internas locais de métodos só podem ser instanciadas dentro do método onde foram criadas e acessam normalmente os membros privados da classe externa, entretanto não poderão usar as variáveis locais do método onde elas estiverem. A única exceção é no caso de as variáveis serem final. Veja o código a seguir:
class TestaClasseLocalMetodo {
   public void fazAlgo() {
      int x = 1;
      class ClasseInvalida {
         public void naoRoda() {
            System.out.println("x = " + x); // não compila. 'x' não está visível. Solução: declarar 'x' como final
         }
      }
   }
}
    1. Em classes internas anônimas, tome cuidado com o ponto-e-vírgula de fechamento da definição da classe. Caso ele não esteja presente, o código não compila. Observe o exemplo:
public class Animal {
   public void pula() {
      System.out.println("pulou");
   }
}

class Cachorro {
   Animal a = new Animal() {
      public void pula() {
         System.out.println("pulo 2");
      }
   } // Não compila. Falta ponto-e-vírgula
}
    1. Saiba identificar uma classe interna anônima que, ao invés de sobrescrever um método da superclasse, define um método novo.
    2. Cuidado com instanciação de interface ou classes abstratas. O primeiro código a seguir não roda, mas o segundo sim.
Runnable r = new Runnable(); // Não compila. Tentando instanciar uma interface.
Runnable r = new Runnable() { // Compila. Classe anônima.
   public void run() { }
};
    1. É muito importante você saber a maneira como uma thread funciona. O exame tem perguntas a respeito de “comportamento garantido” em concorrência que normalmente caem;
    2. Atenção com métodos run sobrecarregados. A classe Thread espera um método run() sem argumentos e o executará ao iniciá-la.
    3. A classe Thread implementa Runnable, portanto é perfeitamente fazer o seguinte:
Thread t = new Thread(new Thread());
t.start();
  1. Lembre-se que uma vez uma thread tenha sido iniciada, ela jamais pode ser iniciada novamente;
  2. Ao terminar a execução do método sleep(), não significa que a thread retornará ao estado de execução, pois ela fica com o status de executável. O método sleep(), portanto, não deve ser encarado como um timer preciso;
  3. Entenda a estrutura dos comandos javac e java. No teste sempre caem perguntas simples do assunto.
Anúncios
  1. 20/04/2010 às 07:36

    Muito bom Pablo.
    Também sou certificado e muitas das coisas ditas aqui realmente caem no exame!!

    Parabéns!!

  2. 20/04/2010 às 10:39

    Muito bom!

  3. 20/04/2010 às 14:32

    Parabéns Pablo. Eu vou dar uma olhada.

  4. 20/04/2010 às 17:02

    Muito bom o post! Simples e conciso.
    Parabéns!

  5. Neandro Ramos
    20/04/2010 às 18:25

    Muito bom!

  6. Glaydson Maget
    20/04/2010 às 21:18

    Show,

    excelentes dicas, muito valiosas e sem dúvida vão me ajudar bastante.

  7. 21/04/2010 às 14:29

    opa! Pablo, Parabens pelo post, realmente execelente. Simples e direto. 😀
    flw, abracos,

  8. Fabiano Piazzarolo
    14/05/2010 às 12:02

    O material está muito interessante. Para quem está em dúvida sobre o quanto está preparado para o exame esse material já pode dar uma idéia. Parabéns mt bom!!

  9. Roberto A. F. Lisbôa
    09/06/2010 às 09:02

    Olá, mto bom o post.
    Parabéns.

  10. joao
    24/08/2010 às 12:40

    Só uma obs. Vc diz “Runnable r = new Runnable(); // Não compila. Tentando instanciar uma classe abstrata.”.Porem Runnable não é classe abstrata e sim interface.

    Parabéns pelo post eu li e ajuda mto…

  11. 11/11/2010 às 14:48

    muito bom o post! parabens !

  12. Suiane
    06/02/2011 às 12:00

    Parabéns pelo seu blog e principalmente pelas dicas.

  13. Lukas
    18/11/2011 às 09:29

    Quero tirar a certificação tb, e eu tenho o livro – ‘Certificação SUN para Programador Java 5’

    A questão é, quero fazer a certificação p/SCJP6 e não p/5. O livro que eu tenho que é o guia p/certificação 5 é válido p/eu estudar p/prova SCJP6, sei que a versão 6 tem + 3 classes na API

    • 18/11/2011 às 09:43

      Dá para tirar, sim, pelo livro SCJP5. São poucas diferenças, como essas 3 classes novas que você falou (e mais algumas interfaces). Eu apenas procuraria na internet uma fonte que explicasse o que veio de novo da versão 5 para a 6 para ficar informado. Aqui tem um link.

  14. jaumzera
    15/03/2012 às 17:36

    Valeu’ brotha…. minha prova é amanhã. Suas dicas vão ser muito úteis

    • 15/03/2012 às 18:52

      Blz, João. Boa sorte amanhã.

      • jaumzera
        11/02/2015 às 09:23

        Vixe… quanto tempo… ^^).
        Fiz mesmo a prova no dia seguinte: 92%.

      • 11/02/2015 às 11:09

        Parabéns. Índice realmente muito bom!

  15. 19/04/2012 às 09:21

    Parabéns!! ótimas dicas…

  16. Romario
    18/07/2012 às 11:42

    ótima dicas Pablo parabéns brother

  17. Diogenes
    04/09/2012 às 17:59

    Men, Assim como classes internas (exceto local method class e anonymous class) Enums (Not top-level) podem ter acesso private ou protected !?
    …Axo que Enums (necessariamente public and default) somente quando forem top-level e (necessariamente public mesmo que implicitamente) quando declarado dento de interface

    • 04/09/2012 às 20:22

      Verdade, Diógenes. Enums fora de uma classe é que não podem ter acesso private ou protected. Vou corrigir. Abraço.

  18. Alessandra
    12/02/2013 às 23:20

    Muito obrigada =). Essas dicas vão ajudar bastante .

  19. jonatha
    02/08/2013 às 15:07

    Parabéns ficou muito Bom,
    Fiquei somente com uma duvida quando realizo a conversão de array para lista e faço uma alteração em qualquer das abas as parte, uma afeta a outra. porem fiz um teste com o contrario convertendo uma List para um array utilizando o toArray(), em seguida realizei as alterações em abas as partem porem nenhuma afetou a outra.

    Outra observação é que depois da conversão de Array para Coleção não ser pode adicionar mais nada na coleção somente realizar alterações.
    porém depois de uma conversão de Coleção para um Array pode realizar qualquer alteração em abas as parte inclusive adicionar novos elementos.

    • 02/08/2013 às 16:24

      Jonatha,

      Você tem toda razão. Ao usar o toArray() e modificar o conteúdo do array não modifica a Collection. Vou corrigir.

      Abraço,

      Pablo.

  1. 20/04/2010 às 17:16
  2. 03/01/2011 às 23:29
  3. 24/03/2014 às 12:53

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: