Tipo de campo Java para um valor de um tipo automático genericamente recursiv
Forneceu uma hierarquia de classes em que a classe base define um tipo automático recursivo:
abstract class A<T extends A<T>> { }
Como posso declarar outra classe (que não deve ser genérica em T, porque esse T pode variar ao longo da vida útil do objeto) com um campo que pode conter qualquer subclasse de A?
O seguinte não funciona:
public class B {
//fails to compile, because the capture of ? is not sufficiently narrow
private A<?> a;
public <T extends A<T>> setA(T a) {
this.a = a;
}
}
- FIM DA PERGUNTA -
Eu notei a tendência de vários membros do StackOverflow de abordar certas questões difíceis com "por que você está fazendo isso em primeiro lugar?" A seguir, uma justificativa do meu uso desse padrão - você pode observar que a biblioteca padrão Java também usa tipos automáticos recursivos em sua definição da classe Enum:Enum<E extends Enum<E>>
. Essa pergunta pode ser feita da mesma forma como "como definir um campo do tipoEnum<?>
.
Exemplo de justificação:
abstract class A<T extends A<T>> {
public abtract T self();
public B<T> bify(Bifyer bifyer) {
return bifyer.bify(self());
}
}
com subclasses:
class ASub1 extends A<ASub1> {
public ASub1 self() { return this; }
}
class ASub2 extends A<ASub2> {
public ASub2 self() { return this; }
}
bound a uma hierarquia de classes paralela:
abstract class B<T extends A<T>> {
}
class BSub1<T extends A<T>> implements B<T> { }
class BSub2<T extends A<T>> implements B<T> { }
//and others
E com a geração de instâncias B gerenciadas por implementações de uma interface Bifyer:
interface Bifyer {
B<ASub1> bify(ASub1 asub1);
B<ASub2> bify(ASub2 asub2);
}
s implementações desta interface podem retornar um BSub1 ou BSub2 para o B. Esta é essencialmente uma aplicação do padrão Visitor, onde o Bifyer é o visitante, mas, diferentemente do Visitor padrão, o método accept retorna um valor em vez de nulo. Isso fornece uma estrutura modular em que diferentes implementações do Bifyer podem ser especificadas para fornecer comportamento alternativo e tipos de retorno para o método Bify - digamos, um para cada subclasse de B.