2010-05-07 18 views

Respuesta

7

Las estructuras simuladas no crean interfaces de instancia, sino que crean clases que las implementan sobre la marcha en tiempo de ejecución. ¡Puede encontrar this javadoc enlightening para lo que quiere hacer!

2

No puede crear una instancia de una clase que no está completamente especificada.

Para ilustrar, llamando newInstance() en una clase de tipo Class<Object> sin duda lo cree un objeto, pero llamar newInstance() en una clase de tipo Class<?> dejaría el compilador preguntándose qué clase de todo el universo de posibilidades que se debe construir.

El hecho de que usted ha reducido el campo un poco especificando que en vez de ?, que desea una ? que se extiende Annotation no quiere decir que en realidad ha nombrado una clase particular de construir. ? extends Annotation solo significa "alguna clase que se extiende Annotation" Sin nombrar la clase exacta, el Cargador de clases no puede determinar qué constructor llamar, porque no hay límite en el número de clases que pueden extenderse Annotation.

EasyMock no crea instancias de interfaces. No estoy familiarizado con el marco, pero es probable que ejemplifique java.lang.Object (s) que extiendan la interfaz deseada, o ejemplifica algún tipo de clase de marco "detrás de escena" que se generó con una cláusula "implementa la interfaz" en la definición de clase. Las interfaces no tienen un constructor predeterminado.

+0

Creo que EasyMock usa CGLIB. Mockito usa CGLIB. CGLIB es una biblioteca que le permite crear un objeto proxy. Es más rápido que el proxy Java, ya que crea/manipula bytecode. – mjlee

+0

EasyMock parece generar una clase con un nombre similar a $ Proxy0. El signo $ representa típicamente un nombre de clase interno/generado, y el 0 probablemente sea el número de clase imitado interno de acuerdo con la arquitectura interna de EasyMock. Así que el modo fácil aún crea una clase, no una interfaz; sin embargo, crea una clase que obviamente implementa la interfaz. –

+0

Esta respuesta simplemente no tiene sentido. Hay tipos de comodines en la JVM pero nunca representan un tipo concreto. Cualquier puntero? Siempre se refiere a un tipo concreto. –

7

Gracias a Affe por orientarme en la dirección correcta, comentaría su respuesta, pero no podría formatear la solución:

Annotation annotation = (Annotation) Proxy.newProxyInstance(
    clazz.getClassLoader(), 
    new Class[] { Annotation.class }, 
    new InvocationHandler() { 
    @Override public Object invoke(Object proxy, Method method, Object[] args) { 
     return clazz; // only getClass() or annotationType() should be called. 
    } 
    });
funciona como un encanto.

+4

No puedo entender qué posible _good_ podría ser esta instancia de anotación rota. Es como si hubiera pedido una hamburguesa y obtuve una fotocopia de una vieja fotografía en blanco y negro de un sándwich de jamón. ¿Explique? –

+0

Estoy trabajando con el código Guice que trata con anotaciones vinculantes. Excepto por '@ Named', solo' annotationType() 'y tal vez' getClass() 'se invocan en las' Anotaciones 'que paso al método que estoy llamando. Así que mientras mi 'Anotación' pueda imitar esos métodos, funcionará bien. – Steve

+0

@Steve 'getClass()' no pasará al 'InvocationHandler' y devuelve' Proxy.class'. Pero probablemente quieras 'toString()' para el depurador. – Brainlag

0

Si conoce el tipo de anotación en tiempo de compilación, puede crear una clase que implemente la anotación como si fuera una anotación normal. Consulte también this answer.

Cuestiones relacionadas