I have a Class<? extends Annotation>
and tried calling newInstance()
but Java yelled at me for the obvious reason that I can't instantiate an interface. But I know frameworks like EasyMock are perfectly capable of instantiating interfaces. What would it take to get a completely dumb Annotation
instance out of my Class
?
问题:
回答1:
Mock frameworks do not instantiate interfaces, they build classes that implement them on the fly at runtime. You may find this javadoc enlightening for what you want to do!
回答2:
Thanks to Affe for pointing me the right direction - I'd comment on his answer but then I wouldn't be able to format the solution:
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. } });works like a charm.
回答3:
You can't create an instance of a class that's not fully specified.
To illustrate, calling newInstance()
on a class of type Class<Object>
would definately create an Object, but calling newInstance()
on a class of type Class<?>
would leave the compiler wondering which class out of the entire universe of possibilities it should construct.
Just because you have narrowed the field down a bit by specifying that instead of just ?
, you want a ?
that extends Annotation
doesn't mean you've actually named a particular class to construct. ? extends Annotation
just means "some class that extends Annotation
" Without naming the exact class, the ClassLoader cannot figure out which constructor to call, because there is no limit to the number of classes that might extend Annotation
.
EasyMock doesn't instantiate Interfaces. I'm not familiar with the framework, but it likely instantiates java.lang.Object(s) which extend the desired interface, or it instantiates some sort of "behind the scenes" framework class which was generated with an "implements interface" clause in the class definition. Interfaces don't have a default constructor.
回答4:
If you know the type of the annotation at compile time, you can just create a class that implements the annotation as if it was a normal annotation. See also this answer.