Classe aninhadas no Java (Nested Classes)
Tags: java, poo, backend, backenddevelopment
Published: 2023-08-02 14:49:04

Uma classe aninhada (Nested Classes) é definida dentro de outra. Seu objetivo é atender necessidades da sua classe envolvente. 

Há quatro tipos de classes aninhadas: 

- Classes membro estáticas(static nested classes)
- Classes membro não estáticas(inner classes)
- Classes anônimas 
- Classes locais

Diferente das classes externas que só podem ter os modificadores de acesso  public or package private, essas classes podem ser private, public, protected or package private

Outra diferença é que todas elas (exceto o primeiro tipo, por ser estática), são classificadas como classes internas. 

![Exemplos de Classes Aninhadas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gj8hu1ra40l664rlat6d.png)

- Classes membro estáticas: É como se fosse uma classe de nível superior estática comum, com a diferença de ter sido criada em outra classe de nível superior. Ela obedece as mesmas regras de acessibilidade que qualquer outro membro estático da classe em que está envolvida, e portanto NÃO possuem acesso e não podem se referir diretamente a variáveis ​​de instância ou métodos definidos em sua classe envolvente, podendo usá-los apenas por meio de uma referência de objeto. Ela também é instanciada da mesma forma que qualquer outra classe:
ClasseAninhadaEstatica classeAninhadaEstatica = new ClasseAninhadaEstatica(); 

- Classes membro não estáticas: Está sempre associada à classe em que está envolvida, por isso não pode ser acessada “de fora” e também não pode definir nenhum membro estático. Elas possuem acesso aos outros membros da classe envolvente, mesmo se eles forem private. Esse tipo de classe é comumente utilizada com o Padrão Adaptador. Ex: Interface Map, método keySet.
Para instanciar uma classe interna, primeiro precisamos instanciar a classe externa.
ClasseQualquer classeQualquer = new ClasseQualquer(); 
ClasseQualquer.ClasseMembro classeMembro = classeQualquer.new classeMembro();

As classes locais e classes anônimas são tipos de classes internas.

- Classes anônimas: Uma classe anônima é uma expressão. Elas permitem que você declare e instancie uma classe ao mesmo tempo. Existem apenas dentro do corpo de um método, SEM nomear a classe. É declarada e instanciada no momento da utilização, não têm nome e não são um membro de sua classe envolvente. Podem ser criadas em qualquer lugar do código em que uma expressão seja aceitável e por isso devem permanecer curtas(geralmente no máx. 10 linhas). Não permitem implementar muitas interfaces ou estender uma classe e implementar uma interface ao mesmo tempo. 

As classes anônimas são ideais para implementar uma interface que contém dois ou mais métodos. Caso contenha um método só, podem ser declaradas como expressões lambdas.

- Classes locais: Uma classe interna dentro do corpo de um método. Menos utilizadas, podem ser declaradas em qualquer lugar que uma variável local pode ser declarada e obedecem às mesmas regras de escopo. Também devem ser curtas.

Qual tipo de classe aninhada utilizar?
Se uma classe aninhada precisa ser visível fora de um único método ou é muito longa, é recomendável utilizar uma classe membro. Se ela precisa de referência à sua classe envolvente, deve ser uma classe não-estática, mas caso contrário, deixe-a estática. 

Se a classe está dentro de um método, caso precise criar instâncias dela, utilize uma classe anônima. Se não, utilize uma classe local.


*Baseado na documentação do Java e no livro "Java Efetivo".