¿Tipo de campo Java para un valor de un tipo automático genéricamente recursivo?

Dado una jerarquía de clases donde la clase base define un auto-tipo recursivo:

abstract class A<T extends A<T>> { }

¿Cómo puedo declarar otra clase (que no debería ser genérica en T, porque dicha T podría variar durante la vida útil del objeto) con un campo que pueda contener cualquier subclase de A?

Lo siguiente no 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;
    }
}

- FIN DE LA PREGUNTA -

He notado una tendencia de varios miembros de StackOverflow a abordar ciertas preguntas difíciles con "¿por qué estás haciendo eso en primer lugar?" La siguiente es una justificación de mi uso de este patrón: puede observar que la biblioteca estándar de Java también usa auto-tipos recursivos en su definición de la clase Enum:Enum<E extends Enum<E>>. Esta pregunta también podría formularse como "cómo definir un campo de tipoEnum<?>.

Ejemplo de justificación:

abstract class A<T extends A<T>> {
    public abtract T self();
    public B<T> bify(Bifyer bifyer) {
        return bifyer.bify(self());
    }
}

con subclases:

class ASub1 extends A<ASub1> { 
    public ASub1 self() { return this; }
}       

class ASub2 extends A<ASub2> { 
    public ASub2 self() { return this; }
}       

bound a una jerarquía de clases paralelas:

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

Y con la generación de instancias B gestionadas por implementaciones de una interfaz Bifyer:

interface Bifyer {
    B<ASub1> bify(ASub1 asub1);
    B<ASub2> bify(ASub2 asub2);        
}

Las implementaciones de esta interfaz pueden devolver un BSub1 o BSub2 para B. Esta es esencialmente una aplicación del patrón Visitor donde Bifyer es el visitante, pero a diferencia del Visitor estándar, el método accept devuelve un valor en lugar de nulo. Esto proporciona un marco modular donde se pueden especificar diferentes implementaciones de Bifyer para proporcionar comportamientos alternativos y tipos de retorno para el método Bify, por ejemplo, uno para cada subclase de B.

Respuestas a la pregunta(1)

Su respuesta a la pregunta