📌 O que são inner classes?
Inner classes são classes declaradas dentro de outras classes. Elas ajudam a organizar o código e permitem acessar membros da classe externa. Existem 4 tipos principais:
✅ 1. Nested Static Class (Classe estática aninhada)
É uma classe estática definida dentro de outra classe.
Não tem acesso direto a membros não estáticos da classe externa.
public class Externa {
static class Interna {
void mostrar() {
System.out.println("inner class estática");
}
}
public static void main(String[] args) {
Externa.Interna obj = new Externa.Interna();
obj.mostrar();
}
}
❌ Errado:
public class Externa {
int x = 10;
static class Interna {
void erro() {
// ERRO: não pode acessar o x
// pq é uma instância da externa
System.out.println(x);
}
}
}
✅ 2. Member Inner Class (Classe interna não estática)
- Declarada sem
staticdentro da classe. - Precisa de uma instância da classe externa para ser usada.
- Pode acessar membros da externa, inclusive privados.
public class Externa {
private String msg = "Olá";
class Interna {
void mostrar() {
// acessa membro da externa
System.out.println(msg);
}
}
public static void main(String[] args) {
Externa externa = new Externa();
Externa.Interna interna = externa.new Interna();
interna.mostrar();
}
}
✅ 3. Local Inner Class (Classe interna local)
Definida dentro de um método.
Só visível dentro do método.
Pode acessar variáveis finais ou efetivamente finais do método.
public class Teste {
void metodo() {
final int valor = 10;
class Interna {
void exibir() {
System.out.println("Valor: " + valor);
}
}
Interna i = new Interna();
i.exibir();
}
public static void main(String[] args) {
new Teste().metodo();
}
}
❌ Errado (variável não final ou efetivamente final):
void metodo() {
int x = 10;
// agora x não é mais efetivamente final
x = 20;
class Interna {
void show() {
// ERRO!
System.out.println(x);
}
}
}
✅ 4. Anonymous Inner Class (Classe anônima)
Classe sem nome, usada geralmente para implementar uma interface ou estender uma classe abstrata de forma rápida.
Criada no momento da instanciação.
interface Saudacao {
void dizer();
}
public class Teste {
public static void main(String[] args) {
Saudacao s = new Saudacao() {
public void dizer() {
System.out.println("Oi anônimo!");
}
};
s.dizer();
}
}
💣 Pegadinhas comuns:
- Nested static class não acessa membros de instância da externa.
- Local inner class só acessa variáveis
finalou efetivamente final. - Anonymous inner class não pode ter construtor.
- A classe interna não estática precisa de instância da externa.
- Inner classes podem ser privadas, protegidas, públicas ou padrão.
📝Hora do Simulado
1) Dado o seguinte código:
Gabarito: B – Erro de compilação: não é possível acessar Interna
public class Teste {
private String msg = "Oi";
class Interna {
void mostrar() {
System.out.println(msg);
}
}
public static void main(String[] args) {
Interna i = new Interna();
i.mostrar();
}
}
O que acontece?
A) Compila e imprime “Oi”
B) Erro de compilação: não é possível acessar Interna
C) Erro de execução
D) Erro de compilação: variável msg precisa ser final
2) Qual código compila corretamente?
Gabarito: A – Compila corretamente
A)
public class Teste {
static class Interna {
void show() {
System.out.println("Oi");
}
}
public static void main(String[] args) {
new Interna().show();
}
}
B)
public class Teste {
class Interna {
void show() {
System.out.println("Oi");
}
}
public static void main(String[] args) {
Interna i = new Interna();
i.show();
}
}
C)
public class Teste {
class Interna {
void show() {
System.out.println("Oi");
}
}
public static void main(String[] args) {
Teste.Interna i = new Teste.Interna();
i.show();
}
}
3) O que acontece ao tentar compilar este código?
Gabarito: C – Erro porque variável x não é efetivamente final
int x = 5;
x = 10; // ← perdeu a “finalidade”
➡️ Variáveis acessadas dentro de uma classe local (dentro de método) devem ser final ou efetivamente final.
public class Teste {
void metodo() {
int x = 5;
x = 10;
class Interna {
void show() {
System.out.println(x);
}
}
new Interna().show();
}
}
A) Compila normalmente
B) Erro porque classe local não pode acessar variável x
C) Erro porque variável x não é efetivamente final
D) Erro de tempo de execução
4) Sobre anonymous inner class, qual é falso?
Gabarito: C
A) Pode ser usada para instanciar uma interface
B) Pode estender uma classe abstrata
C) Pode conter construtores
D) Pode acessar membros da classe externa
5) Qual das opções define corretamente uma classe anônima que implementa Runnable?
✅Gabarito: A
❌C) É uma lambda expression, válida, mas não é uma inner class anônima, e a questão pediu especificamente isso.
A)
Runnable r = new Runnable() {
public void run() {
System.out.println("Rodando");
}
};
B)
Runnable r = new Runnable {
public void run() {
System.out.println("Rodando");
}
};
C)
Runnable r = () -> System.out.println("Rodando");
D) Todas as anteriores
🧠 RESUMO: Inner Classes em Java
| Tipo | Palavra-chave | Onde é declarada | Pode acessar membros da classe externa? | Precisa de instância da externa? |
|---|---|---|---|---|
| Nested Static Class | static | Dentro da classe | ❌ Somente membros static | ❌ |
| Member Inner Class | (sem static) | Dentro da classe | ✅ Sim | ✅ |
| Local Class | (sem static) | Dentro de um método | ✅ Sim (variáveis final/efetivamente final) | ⚠️ Só dentro do método |
| Anonymous Inner Class | (sem nome) | No momento da instanciação | ✅ Sim | ⚠️ Não tem construtor próprio |