2008-09-01 35 views
9

¿Hay alguna forma taquigráfica de definir y usar definaciones genéricas sin tener que seguir repitiendo una descripción genérica particular de modo que si hay un cambio no tengo que cambiar todas las definiciones/usos aunque fuera el código base, por ejemplo se somethhing como esto sea posible:genéricos en Java

Typedef myGenDef = < Object1, Object2 >; 

HashMap<myGenDef> hm = new HashMap<myGenDef>(); 

for (Entry<myGenDef> ent : hm..entrySet()) 
{ 
. 
. 
. 
} 

Respuesta

11

Ahí está el pseudo-typedef antipattern ...

class StringList extends ArrayList<String> { } 

¡Buenas cosas, bebida! ;-)

Como señala el artículo, esta técnica tiene algunos problemas serios, principalmente que este "typedef" es en realidad una clase separada y por lo tanto no puede usarse indistintamente con el tipo que se extiende u otros tipos definidos de manera similar.

+0

Puede no ser una buena idea aceptar un antipatrón como una solución a su pregunta, especialmente cuando hay alternativas. Pero si te ayudó con tu problema en particular ... –

+0

(Sin tener en cuenta la advertencia de los moderadores sobre el ruido en los hilos "typedef en Java") ... Eso es peor que un antipatrón. Crea un nuevo tipo de primera clase, con sus propias entradas en las tablas de métodos virtuales y todas esas obligaciones.Un typedef de C++ simplemente haría que la parte "ArrayList " DRY, por lo que puede cambiar String (o ArrayList) en un solo lugar. – Phlip

+0

Sí, C/C++ typedefs es una característica de idioma muy respetado con buen soporte y muchos usos legítimos. Esto no es. De ahí todo el asunto "antipattern". – Shog9

1

No. Aunque, maravilloso, un lenguaje de JVM, se escribe de forma dinámica y dejaría que se escribe:

def map = new HashMap<complicated generic expression>(); 
+0

Lo mismo con Scala. Estos lenguajes ofrecen una sintaxis que puede inferir tipos a partir de sentencias de instanciación de variables. Esto es similar a lo que se ofrece en .NET con la palabra clave var. No confundas esto con lenguajes débilmente (o flojos) que te permiten aventurar un tipo de variable sobre la marcha; la JVM aún impone una escritura fuerte en su código compilado. –

4

En un método genérico, puede utilizar una forma limitada de tipo inferrence para evitar algunas repeticiones.

Ejemplo: si tiene la función

<K, V> Map<K, V> getSomething() { 
     //... 
    } 

que puede utilizar:

final Map<String, Object> something = getsomething(); 

en lugar de:

final Map<String, Object> something = this.<String, Object>getsomething(); 
3

Uso Factory Pattern para la creación de los genéricos:

Método de muestreo:

public Map<String, Integer> createGenMap(){ 
     return new HashMap<String,Integer>(); 

    } 
2

El anti patrón pseudo-typedef mencionado por Shog9 funcionaría - aunque no se recomienda el uso de un anti patrón - pero no frente a sus intenciones. El objetivo de pseudo-typedef es reducir el desorden en la declaración y mejorar la legibilidad.

Lo que quiere es poder reemplazar un grupo de declaraciones de genéricos por una sola operación. Creo que tienes que parar y pensar: "¿De qué forma es valioso?". Quiero decir, no puedo pensar en un escenario donde necesitarías esto. Imagine clase A:

class A { 
    private Map<String, Integer> values = new HashMap<String, Integer>(); 
} 

Imagínese ahora que quiero cambiar el campo 'valores' a un Mapa. ¿Por qué existirían muchos otros campos diseminados a través del código que necesita el mismo cambio? En cuanto a las operaciones que usan 'valores', una simple refactorización sería suficiente.