Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to instantiate a Java Annotation given a Class<? extends Annotation>?

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?

like image 690
Steve Avatar asked May 07 '10 04:05

Steve


3 Answers

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!

like image 124
Affe Avatar answered Sep 18 '22 10:09

Affe


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.

like image 41
Steve Avatar answered Sep 18 '22 10:09

Steve


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.

like image 37
Edwin Buck Avatar answered Sep 21 '22 10:09

Edwin Buck