Tengo un conjunto bastante complicado de clases genéricas en Java. Por ejemplo, tengo una interfazEscriba alias para los genéricos de Java
interface Doable<X,Y> {
X doIt(Y y);
}
y la implementación
class DoableImpl implements Doable<Foo<Bar<Baz,Qux>>,Foo<Bar<Zot,Qux>>> {
Foo<Bar<Baz,Qux>> doIt(Foo<Bar<Zot,Qux>> fooBZQ) { ... }
}
En la implementación real, Doable
tiene un buen número de métodos y así Foo<Bar<Baz,Qux>>
, etc., aparecen una y otra vez. (Créalo o no, los tipos genéricos son un poco más dolorosos que este. Los simplifiqué para el ejemplo.)
Me gustaría simplificar estos, ahorrarme tipeo y aliviar la tensión en mis ojos Lo que me gustaría es tener un simple "alias de tipo" para Foo<Bar<Baz,Qux>>
, etc., digamos FooBBQ
y FooBZQ
.
Mi idea actual es definir clases contenedoras:
class FooBBQ {
public static FooBBQ valueOf(Foo<Bar<Baz,Qux>> fooBBQ) {
return new FooBBQ(fooBBQ);
}
private Foo<Bar<Baz,Qux>> fooBBQ;
private FooBBQ(Foo<Bar<Baz,Qux>> fooBBQ) {
this.fooBBQ = fooBBQ;
}
public Foo<Bar<Baz,Qux>> toGeneric() {
return fooBBQ;
}
}
class FooBZQ { /* pretty much the same... */ }
class DoableImpl implements Doable<FooBBQ,FooBZQ> {
FooBBQ doIt(FooBZQ fooBZQ) { ... }
}
Esto funciona bien, pero tiene algunos inconvenientes:
- Tenemos que definir envolturas separadas para cada instancia genérica. Las clases de envoltura son cortas y estilizadas, pero no puedo encontrar una manera de macro -izarlas.
Tenemos la sobrecarga de traducción (conceptualmente, si no operacionalmente) de llamar a
valueOf
ytoGeneric
para convertir entreFooBBQ
yFoo<Bar<Baz,Qux>>
. Por ejemplo, sidoIt
llamadas en alguna rutina de biblioteca que espera unFoo<Bar<Zot,Qux>>
(que la implementación real lo hace), que terminan con algo comoreturn FooBBQ.valueOf(libraryCall(fooBZQ.toGeneric()))
en el que originalmente habría tenido
return libraryCall(fooBZQ);
¿Hay alguna otra forma de obtener el comportamiento de "tipo de alias" que quiero aquí? ¿Tal vez usando algún conjunto de herramientas macro de terceros? ¿O tengo que aceptar que voy a tener que escribir mucho, de una manera (usando los tipos genéricos en la implementación) o de la otra (escribiendo envoltorios para ellos)? Tal vez tener tantos parámetros genéricos volando es solo una mala idea y necesito volver a pensar el problema.
[ACTUALIZAR] OK, estoy prohibiendo cualquier respuesta adicional de "no hacer eso". Tómalo como un hecho que Foo<Bar<Baz,Qux>>
tiene un valor genuino en mi dominio problemático (Pete Kirkham puede tener razón en que tiene valor suficiente para obtener una clase contenedora adecuada con un nombre descriptivo). Pero este es un problema de programación; no trates de definir el problema.
Voy a decir 'probablemente sí' a la última, pero realmente no tengo comentarios constructivos: P ¡Parece un desastre! ¡Buena suerte! –
Creo que esta pregunta sería una buena propuesta para Java. Si pudieras proponer una característica de Alias de Tipo a Oracle, creo que sería una gran característica de lenguaje que simplificará el idioma y hará que el código fuente sea más legible. –
Con la profundidad de la rodilla en Java hoy y quería limpiar un código detallado ... no solo no obtengo la inferencia de tipo, sino tampoco el alias de tipo. * sollozo * –