Is it possible to instantiate a Java Annotation gi

2019-05-02 18:50发布

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?

4条回答
姐就是有狂的资本
2楼-- · 2019-05-02 19:17

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.

查看更多
▲ chillily
3楼-- · 2019-05-02 19:20

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.

查看更多
家丑人穷心不美
4楼-- · 2019-05-02 19:27

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!

查看更多
5楼-- · 2019-05-02 19:37

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.

查看更多
登录 后发表回答