Início > programação > 50 dicas práticas para o exame SCJP Java 6

50 dicas práticas para o exame SCJP 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 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:
  10. int x = 1;
    if (x) { } // Erro do compilador
    

  11. Tome cuidado com variáveis sombreadas e  com erros de escopo em blocos de código como switches, try-catches e loops;
  12. 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:
  13. 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

  14. 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.
  15. Integer[] inteiros = new Integer[5];
    

  16. 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:
  17. 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
       }
    }
    

  18. 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:
  19. 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
       }
    }
    

  20. 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;
  21. 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;
  22. Você deve compreender de forma clara como a concatenação de Strings funciona, principalmente dentro de uma instrução print. Veja o exemplo abaixo:
  23. int b = 2;
    System.out.println("" + b + 3); // Imprime '23'
    System.out.println(b+3); // Imprime 5
    

  24. 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.
  25. 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:
  26. if (5 && 6) // Erro de compilação.
    

  27. 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.
  28. 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:
  29. 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();
    }
    

  30. 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.
  31. 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:
  32. String teste = "teste";
    System.out.println(teste.length); // Erro de compilação
    }
    

  33. 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:
  34. 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.
    

  35. 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:
  36. 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

  37. Atenção: a contagem dos meses em um Calendar começa em 0 (zero);
  38. 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:
  39. class TestaLocal {
       public static void main(String[] args) {
          DateFormat df = DateFormate.getInstance();
          df.setLocale(new Locale("it", "IT"));
       }
    }
    

  40. Metacaracteres e Strings não trabalham bem juntos. Portanto, tome cuidado com código como o abaixo, pois ele não compila:
  41. class TestaPattern {
       public static void main(String[] args) {
          String patternInvalido= "\d"; // Pattern inválido. Não compila.
          Pattern p = Pattern.compile(patternInvalido);
       }
    }
    

  42. 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:
  43. class ErroEquals {
       boolean equals(Object o) { // visibilidade default: não compila
          return false;
       }
    }
    

    class Bola {
       boolean equals(Bola bola) { // sobrecarga válida
          return true;
       }
    }
    

  44. 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;
  45. 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;
  46. É 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:
  47. class TestaMap {
       public static void main(String[] args) {
          Map<String, String> mapa  = new Map<String, String>();
       }
    }
    

  48. 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;
  49. Procure por questões no exame que tentem classificar um array de primitivos usando um Comparator, o que é inválido;
  50. 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;
  51. 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;
  52. Quando converter arrays em Collections ou Collections em arrays, lembre-se que a atualização em um dos objetos refletirá no outro. Observe o código abaixo:
  53. class TestaColecoes {
       public static void main(String[] args) {
          String[] nomes = {"Pablo", "Nóbrega"};
          List nomesList = Arrays.asList(nomes);
          System.out.println("Posição 1 = " + nomesList.get(1));
          nomesList.set(1, " - Autor do Post");
          for (String s : nomes) {
             System.out.print(s);
          }
       }
    }
    

    A saída para esse código será:
    Posição 1 = Nóbrega
    Pablo – Autor do Post

  54. 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;
  55. 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:
  56. class TestaGenericos {
       public static void main(String[] args) {
          List teste = new ArrayList();
          teste.add(43);
          int x = teste.get(0);
          System.out.println(x);
       }
    }
    

  57. 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:
  58. class TestaGenericos {
       public static void main(String[] args) {
          List<?> animais =   new ArrayList<? extends Animal>();
       }
    }
    

  59. 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:
  60. 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
             }
          }
       }
    }
    

  61. 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:
  62. 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
    }
    

  63. Saiba identificar uma classe interna anônima que, ao invés de sobrescrever um método da superclasse, define um método novo.
  64. Cuidado com instanciação de interface ou classes abstratas. O primeiro código a seguir não roda, mas o segundo sim.
  65. Runnable r = new Runnable(); // Não compila. Tentando instanciar uma interface.
    

    Runnable r = new Runnable() { // Compila. Classe anônima.
       public void run() { }
    };
    

  66. É 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;
  67. Atenção com métodos run sobrecarregados. A classe Thread espera um método run() sem argumentos e o executará ao iniciá-la.
  68. A classe Thread implementa Runnable, portanto é perfeitamente fazer o seguinte:
  69. Thread t = new Thread(new Thread());
    t.start();
    

  70. Lembre-se que uma vez uma thread tenha sido iniciada, ela jamais pode ser iniciada novamente;
  71. 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;
  72. Entenda a estrutura dos comandos javac e java. No teste sempre caem perguntas simples do assunto.
  1. 20/04/2010 às 07:36 | #1

    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 | #2

    Muito bom!

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

    Parabéns Pablo. Eu vou dar uma olhada.

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

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

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

    Muito bom!

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

    Show,

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

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

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

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

    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 | #9

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

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

    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 | #12

    muito bom o post! parabens !

  12. Suiane
    06/02/2011 às 12:00 | #13

    Parabéns pelo seu blog e principalmente pelas dicas.

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

    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 | #15

      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.

  1. 20/04/2010 às 17:16 | #1
  2. 03/01/2011 às 23:29 | #2

Deixe uma resposta

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

WordPress.com Logo

You are commenting using your WordPress.com account. Sair / Alterar )

Imagem do Twitter

You are commenting using your Twitter account. Sair / Alterar )

Foto do Facebook

You are commenting using your Facebook account. Sair / Alterar )

Connecting to %s

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.