Escreva uma classe SerieLimitada, que encapsula um valor inteiro sequencial como os usados em notas e séries de gravuras. Esta classe deve permite que um programa crie um número limitado de instâncias dela, cada uma numerada com um valor sequencial. O número total de instâncias é controlado pelo campo máximoDeInstâncias, declarado como static final e o de instâncias já criadas é controlado pelo campo contador declarado como static. Escreva também um método main que cria algumas instâncias da classe para demonstrar o seu funcionamento.
Passo 1
O enunciado pede uma classe chamada SerieLimitada que gere um número sequencial para cada instância criada, com um limite máximo de instâncias permitido. Os pontos que o enunciado fornece e que precisamos respeitar são:
- Deve existir um campo chamado
maximoDeInstanciasdeclarado comostatic finalque controla o número total máximo de instâncias que a classe permite. - Deve existir um campo chamado
contadordeclarado comostaticque conta quantas instâncias já foram criadas. - A cada nova instância válida deve ser atribuído um valor sequencial inteiro (por exemplo, 1, 2, 3, …).
- Deve haver um
mainque cria algumas instâncias para demonstrar o funcionamento.
Observações importantes que devemos considerar (mas sem resolver ainda): quando o limite for atingido, o construtor precisa impedir a criação de mais instâncias — podemos sinalizar isso lançando uma exceção ou usando outra estratégia; e os camposstaticsignificam que são compartilhados por todas as instâncias da classe.
Passo 2
Vamos decidir a abordagem prática (sem ainda mostrar o código linha a linha):
- Usaremos
public static final int maximoDeInstanciascomo a constante que fixa o limite. Escolherei um valor padrão (por exemplo,5) no código de exemplo, e explicarei como alterar. - Usaremos
private static int contadorpara contar quantas instâncias já foram criadas. Ele começa em0. - Cada objeto terá um campo de instância
private final int numeroque guarda o número sequencial atribuído àquele objeto. - No construtor da classe, verificamos se
contadorjá atingiumaximoDeInstancias. Se sim, lançamos umaIllegalStateExceptioncom uma mensagem clara. Caso contrário, incrementamoscontadore atribuímos o valor anumero. - Mantemos métodos de acesso (getters) para obter o
numeroe ocontador(este último comostatic) para fins de demonstração. - O
maintentará criarmaximoDeInstancias + 1objetos para mostrar o comportamento quando o limite for ultrapassado; envolveremos cada criação em umtry/catchpara capturar a exceção e mostrar uma mensagem amigável.
Motivo da escolha: usar o próprio construtor para validar o limite é a forma mais direta e simples (não exige factory methods) e atende ao enunciado que falou em campos
static e static final. Lançar exceção é uma maneira clara de falhar quando passado o limite — em prova isso é aceitável e demonstra controle de estado.Passo 3
Aula rápida e prática sobre os conceitos usados — nada complicado, só o essencial pra você lembrar na prova:
- Campos
static: são compartilhados por todas as instâncias da classe. Se eu tenhostatic int contador, quando eu façocontador++dentro do construtor, esse mesmocontadoré visto por todas as instâncias. Serve para contagem global. static final: é uma constante de classe.static final int maximoDeInstancias = 5;significa quemaximoDeInstanciasé um valor fixo e visível sem criar instância (acessível comoSerieLimitada.maximoDeInstancias).finalem campo de instância:private final int numero;significa que cada objeto terá umnumeroimutável (atribuído uma vez no construtor).- Lançar exceção quando não for possível criar: usar
throw new IllegalStateException("...")interrompe a criação do objeto e informa o motivo. Emmaina gente captura essa exceção comtry/catchpara demonstrar. - Encapsulamento: manter os campos privados e expor getters ajuda a controlar acesso e seguir boas práticas (útil em provas também).
Exemplo mental simples: pense que cada vez que constrói um objeto você pega a próxima etiqueta numerada (1,2,3…). Quando as etiquetas acabam (maximoDeInstancias), você não pode numerar mais.
Passo 4
Explicação passo a passo do construtor e das operações que vamos codificar (aqui mostro a lógica que você poderia escrever na prova):
- No início do construtor, verificamos
if (contador >= maximoDeInstancias):- Se verdadeiro, fazemos
throw new IllegalStateException("Limite de instâncias (" + maximoDeInstancias + ") atingido");. - Isso garante que, ao tentar criar a (maximo+1)-ésima instância, a criação falha.
- Se verdadeiro, fazemos
- Se não atingiu o limite, incrementamos
contadorcomcontador++. - Atribuímos
this.numero = contador;— assim o primeiro objeto recebe1, o segundo2, e assim por diante. - Mantemos
getNumero()para retornar o número da instância egetContador()(estático) para retornar quantas instâncias já existem (útil nomainpara demonstrar). - No
main, usamos um laço que tenta criarmaximoDeInstancias + 1objetos. Cada tentativa é envolvida numtrye, emcatch (IllegalStateException e), imprimimos uma mensagem explicando que o limite foi alcançado.
Passo 5
Dicas práticas para a prova e variações que podem aparecer:
- Se na prova pedirem que o limite seja configurável em tempo de execução, então
maximoDeInstanciasnão poderia serfinal. Como o enunciado exigestatic final, assumimos que é uma constante conhecida em tempo de compilação. - Se quiser tornar a criação thread-safe, seria preciso sincronizar a região que testa e incrementa
contador. Ex.: sincronizar no blocosynchronized(SerieLimitada.class) { ... }. Aqui vou manter simples, pois a maioria das questões de prova não exige concorrência. - Ao testar localmente, você verá que as primeiras
maximoDeInstanciascriações funcionam e a tentativa seguinte gera a exceção. Isso demonstra que o contador e o limite estão funcionando como desejado.
Passo 6
Agora a implementação final (vou colocá-la no campo de resposta). Nesta implementação:
maximoDeInstanciasecontadortêm os nomes exigidos pelo enunciado.- O construtor faz a validação e atribuição do número sequencial.
- O
maindemonstra a criação demaximoDeInstancias + 1objetos e captura a exceção quando o limite é excedido. - Você pode alterar o valor de
maximoDeInstanciaspara testar com outros limites.
Resposta
public class SerieLimitada {
public static final int maximoDeInstancias = 5;
private static int contador = 0;
private final int numero;
public static final int maximoDeInstancias = 5;
private static int contador = 0;
private final int numero;
public SerieLimitada() {
if (contador >= maximoDeInstancias) {
throw new IllegalStateException("Limite de instâncias (" + maximoDeInstancias + ") atingido");
}
contador++;
this.numero = contador;
}
public int getNumero() {
return numero;
}
public static int getContador() {
return contador;
}
@Override
public String toString() {
return "SerieLimitada#" + numero;
}
public static void main(String[] args) {
System.out.println("Tentando criar " + (maximoDeInstancias + 1) + " instâncias:");
for (int i = 0; i < maximoDeInstancias + 1; i++) {
try {
SerieLimitada s = new SerieLimitada();
System.out.println("Criada: " + s + " (numero=" + s.getNumero() + ", contador=" + SerieLimitada.getContador() + ")");
} catch (IllegalStateException e) {
System.out.println("Falha ao criar instância " + (i + 1) + ": " + e.getMessage());
}
}
}
}