2009-01-20 22 views
5

La idea es definir una clase base que pueda invocar métodos definidos en clases derivadas, pero en el momento de la creación quiero asegurarme de que dichos métodos se definan exactamente de acuerdo con los requisitos, que los métodos toman solo un argumento, una HashMap <String String>.Java: ¿Cómo verificar las definiciones genéricas del tipo de clase?

Hasta ahora pude con el siguiente código comprobar que el método contiene solo un parámetro y que es de Clase HashMap, pero ¿cómo puedo verificar que la definición genérica sea <String, String>?

public boolean isMethodParameterValid(final Method method) { 
    final Class<?>[] parameters = method.getParameterTypes(); 
    return ((parameters.length == 1) && parameters[0].isAssignableFrom(HashMap.class)); 
} 

Respuesta

7

No puede. Los tipos genéricos de Java son "borrados" por el compilador, es decir, HashMap<String, String> pasa a ser HashMap en tiempo de ejecución. Ver pregunta this.

+1

No se borran todos los tipos. Otro ejemplo sería 'new ArrayList {}'. También vale la pena leer la publicación de tokens de Super Type de Neal Gafter: http://gafter.blogspot.com/2006/12/super-type-tokens.html – johnstok

+0

No, el token de super tipo de Neals Gafter se borra en el momento de la compilación. Su truco ayuda a acceder al Tipo utilizado para instanciar el genérico, en tiempo de ejecución (ya que Type.getClass() está autorizado). – JVerstry

1

Realmente no entiendo el objetivo de lo que estás tratando de hacer. Tengo la sensación de que debería ser posible verificarlo en tiempo de compilación mediante el diseño cuidadoso de la jerarquía de clases. Pero sin más detalles sobre el problema que estás tratando de resolver, no puedo ayudarte.

1

Como se indicó, en tiempo de ejecución no puede ver la parte genérica de un tipo.

¿Hay alguna razón por la que simplemente pueda definir un método abstracto como en el Patrón de plantilla?

Luego, la comprobación se realizará estáticamente.

protected abstract void process(HashMap<String, String>); 

(también hay una razón para requerir HashMap más justo mapa?)

12

De hecho, no es el tipo de borrado pero no se aplica a variables/campos - sólo para las definiciones de clases donde el tipo params se borran y se reemplazan con sus límites superiores.

Esto significa que lo que está pidiendo se puede lograr. Aquí se explica cómo puede inspeccionar los parámetros genéricos del primer parámetro de un método:

class Z 
{ 
    public void f(List<String> lst) { } 
} 

... 

Method m = Z.class.getMethod("f", List.class); 
Type t = m.getGenericParameterTypes()[0]; 
if(t instanceof ParameterizedType) { 
    ParameterizedType pt = (ParameterizedType) t; 
    System.out.println("Generic params of first argument: " + Arrays.toString(pt.getActualTypeArguments())); 
}  
+0

Sí. Si tiene una instancia de una clase, en el tiempo de ejecución no puede preguntar cuáles podrían haber sido sus parámetros de tipo genérico. Si tiene un control reflexivo sobre un método, clase o campo que puede haberse definido con parámetros de tipo genérico, puede usar métodos de reflexión para decidir cuáles son esos parámetros genéricos, ya sean tipos, comodines, variables de tipo, etc. – pholser

Cuestiones relacionadas