7 Erros Fatais de Iniciantes em Java (e Como Resolvê-los)
- #Java
Introdução
Cometer erros é parte natural do aprendizado, mas alguns erros custam caro — afetam performance, segurança e a saúde do seu código. Se você está começando com Java, conhecer os 7 erros mais comuns economizará horas de debugging frustrado e te tornará um programador muito mais competente desde o início.
👉 Projeto: Mini_App
* Mini-Aplicativo: Detector de Erros Comuns em Java
* Demonstra: Como evitar os 7 erros mais comunsPegue código Java antigo seu e procure por esses 7 erros. Refatore e compartilhe as melhorias!
https://github.com/edsongom1/java-roadmap-essentials/blob/main/mini_app_java_3.java
Vamos explorar cada erro, entender por que acontece e, acima de tudo, como evitá-lo.
1. ❌ NullPointerException: O Erro Mais Frustrante
O Que Acontece
Você tenta acessar um atributo ou método de um objeto que é null.
java
String texto = null;
System.out.println(texto.length()); // 💥 NullPointerException!
Por Que Ocorre
Você esqueceu de inicializar o objeto ou uma função retornou null inesperadamente.
✅ Como Evitar
java
// ❌ Ruim
String texto = null;
System.out.println(texto.length());
// ✅ Bom: Sempre inicializar
String texto = "";
System.out.println(texto.length()); // 0
// ✅ Melhor: Verificar antes
String texto = obterTexto();
if (texto != null) {
System.out.println(texto.length());
} else {
System.out.println("Texto é nulo!");
}
// ✅ Moderna: Optional (Java 8+)
import java.util.Optional;
Optional<String> texto = Optional.ofNullable(obterTexto());
texto.ifPresent(t -> System.out.println(t.length()));
Regra de Ouro: Sempre assuma que uma função pode retornar null.
2. ❌ Confundindo == com .equals()
O Que Acontece
java
String s1 = new String("Java");
String s2 = new String("Java");
if (s1 == s2) {
System.out.println("São iguais!"); // Não será executado!
}
if (s1.equals(s2)) {
System.out.println("São iguais!");
// ✅ Executado
}
Por Que Ocorre
- == compara referência na memória (endereço)
- .equals() compara conteúdo dos objetos
✅ Como Evitar
java
// ❌ Errado
String a = "Java";
String b = "Java";
if (a == b) { } // Às vezes funciona (string interning), mas não é confiável
// ✅ Correto
String a = "Java";
String b = new String("Java");
if (a.equals(b)) { } // Sempre usa .equals()
// ✅ Ignorar maiúsculas/minúsculas
if (a.equalsIgnoreCase(b)) { }
// ✅ Para números
Integer x = 10;
Integer y = 10;
if (x.equals(y)) { } // Usa .equals() sempre
Regra de Ouro: Use == apenas para comparar primitivos (int, boolean, etc.). Para objetos, use .equals().
3. ❌ Modificar Coleções Enquanto Itera
O Que Acontece
java
List<String> nomes = new ArrayList<>(Arrays.asList("Ana", "Bruno", "Carlos"));
for (String nome : nomes) {
if (nome.equals("Bruno")) {
nomes.remove(nome); // 💥 ConcurrentModificationException!
}
}
Por Que Ocorre
Modificar uma coleção durante iteração quebra o estado interno do iterador.
✅ Como Evitar
java
List<String> nomes = new ArrayList<>(Arrays.asList("Ana", "Bruno", "Carlos"));
// ✅ Opção 1: Usar Iterator
Iterator<String> it = nomes.iterator();
while (it.hasNext()) {
String nome = it.next();
if (nome.equals("Bruno")) {
it.remove(); // Remove seguro
}
}
// ✅ Opção 2: Criar nova lista
List<String> filtrada = nomes.stream()
.filter(n -> !n.equals("Bruno"))
.collect(Collectors.toList());
// ✅ Opção 3: Usar removeIf (Java 8+)
nomes.removeIf(n -> n.equals("Bruno"));
4. ❌ Esquecer break no switch
O Que Acontece
java
int dia = 1;
switch (dia) {
case 1:
System.out.println("Segunda");
// Falta break!
case 2:
System.out.println("Terça");
break;
}
// Saída: Segunda Terça (não esperado!)
Por Que Ocorre
Sem break, o programa continua executando o próximo case (fall-through).
✅ Como Evitar
java
int dia = 1;
switch (dia) {
case 1:
System.out.println("Segunda");
break; // ✅ Sempre adicionar break
case 2:
System.out.println("Terça");
break;
default:
System.out.println("Dia inválido");
}
// Java 14+: Switch expressions (evita automaticamente fall-through)
String nomeDia = switch (dia) {
case 1 -> "Segunda";
case 2 -> "Terça";
default -> "Dia inválido";
};
5. ❌ Ignorar Exceções (Try-Catch Vazio)
O Que Acontece
java
try {
int resultado = 10 / 0;
} catch (Exception e) {
// ❌ Silenciosamente ignora o erro
}
Por Que É Ruim
Você nunca descobre quando algo dá errado. Debugging fica impossível.
✅ Como Evitar
java
// ❌ Nunca faça isto
try {
// código
} catch (Exception e) {
// vazio = silenciosa falha
}
// ✅ Opção 1: Logar o erro
try {
int resultado = 10 / 0;
} catch (ArithmeticException e) {
System.err.println("Erro: " + e.getMessage());
e.printStackTrace();
}
// ✅ Opção 2: Relançar exceção
try {
int resultado = 10 / 0;
} catch (ArithmeticException e) {
throw new RuntimeException("Divisão falhou", e);
}
// ✅ Opção 3: Tratar especificamente
try {
int resultado = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Não é possível dividir por zero!");
} catch (Exception e) {
System.err.println("Erro inesperado: " + e.getMessage());
}
Regra de Ouro: Sempre trate ou relance exceções, nunca ignore!
6. ❌ Usar Tipos de Retorno Incorretos
O Que Acontece
java
// ❌ Retorna void mas tenta usar resultado
public void calcularSoma(int a, int b) {
System.out.println(a + b);
}
int resultado = calcularSoma(5, 3); // Erro de compilação!
✅ Como Evitar
java
// ✅ Retorna o tipo correto
public int calcularSoma(int a, int b) {
return a + b;
}
int resultado = calcularSoma(5, 3); // ✅ Funciona!
// ✅ Se não retorna valor, declare void
public void exibirMensagem(String texto) {
System.out.println(texto);
}
// ✅ Use Optional para retornos que podem ser nulos
public Optional<Integer> obterIdade(String nome) {
if (nome.equals("João")) {
return Optional.of(25);
}
return Optional.empty();
}
idade = obterIdade("João").orElse(0); // Padrão: 0 se vazio
7. ❌ Não Fechar Recursos (Vazamento de Memória)
O Que Acontece
java
// ❌ Arquivo nunca é fechado
FileReader fr = new FileReader("dados.txt");
BufferedReader br = new BufferedReader(fr);
// Se ocorrer erro antes de fechar, recurso vaza
✅ Como Evitar
java
// ✅ Try-with-resources (Java 7+)
try (FileReader fr = new FileReader("dados.txt");
BufferedReader br = new BufferedReader(fr)) {
String linha;
while ((linha = br.readLine()) != null) {
System.out.println(linha);
}
} catch (IOException e) {
e.printStackTrace();
}
// Arquivo fechado automaticamente!
// ✅ Se precisa fechar manualmente
FileReader fr = null;
try {
fr = new FileReader("dados.txt");
// usar arquivo
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Regra de Ouro: Sempre use try-with-resources para arquivos, conexões de BD, etc.
Referências
- Exception Handling: docs.oracle.com/javase/tutorial/essential/exceptions
- Collections: docs.oracle.com/javase/tutorial/collections
- Best Practices: Google Java Style Guide
Conclusão
Os 7 erros apresentados são tão comuns que até programadores experientes os cometem ocasionalmente. A diferença é que profissionais reconhecem os sinais e corrigem rapidamente.
Adotando essas práticas desde agora, você evitará horas de debug frustrante e construirá código robusto desde o início. Lembre-se: código bom é código testado, bem estruturado e seguro.
Chamada para ação
👉 Projeto: Mini_App * Mini-Aplicativo: Detector de Erros Comuns em Java
* Demonstra: Como evitar os 7 erros mais comunsPegue código Java antigo seu e procure por esses 7 erros. Refatore e compartilhe as melhorias!
https://github.com/edsongom1/java-roadmap-essentials/blob/main/mini_app_java_3.java
👉 Exercício: Pegue código Java antigo seu e procure por esses 7 erros. Refatore e compartilhe as melhorias!
📌 Próximo tema: Domine Java Stream API e deixe seu código elegante e funcional.