我写了一个小类,它从方法中读出注释 现在我想扩展该类以使其更具动态性。
我的课目前使用以下代码来读出注释:
ExtendedCommandAnnotation e = foo.getClass()
.getAnnotation(ExtendedCommandAnnotation.class);
String startTag = e.annoPropStartTag();
这是固定注释的简单案例 在新版本中,我没有任何固定的注释。我将在变量中获得注释“ExtendedCommandAnnotation” 因此,上面的代码将被编辑为:
String className= "ExtendedCommandAnnotation";
??? e = foo.getClass().getAnnotation(Class.forName(className));
String startTag = e.annoPropStartTag();
我不知道我要放什么而不是???。我用Annotation尝试过,但后来我无法用定义的方法获得属性 有没有办法让这个工作?
我的注释“类”:
@Retention( RetentionPolicy.RUNTIME )
public @interface ExtendedCommandAnnotation
{
String annoPropUseTab() default "0";
String annoPropStartTag() default "";
String annoPropEndTag() default "";
}
编辑:
最后我得到了类似的东西: String [] cmdMethNames = this.getAvailableCommandNames();
Class<?> annotationClass = Class.forName(this.annotationClassName);
for( Method meth : cmdMeth )
{
HashMap<String, String> tempAnno = new HashMap<String, String>();
if (meth.isAnnotationPresent((Class<? extends Annotation>) annotationClass))
{
Annotation anno = meth.getAnnotation((Class<? extends Annotation>) annotationClass);
[...]
}
[...]
}
但是对(Class<? extends Annotation>)
的强制转换会发出以下警告:“类型安全:未经检查从类&lt; capture#4-of?&gt;转换为类&lt;?extends Annotation&gt; ”< / p>
答案 0 :(得分:2)
如果您事先不知道注释,则无法知道它有annoPropStartTag()
方法,是吗?所以你不能告诉编译器如何绑定到那个方法...
如果你想在执行时基本上找到一个具有该名称的方法,你现在需要使用反射。
您可能需要考虑使用某种“基础”注释类型,其中包含一般情况下所需的所有方法,然后从中派生所有其他注释类型。
答案 1 :(得分:1)
/* Foo.java */
@ExtendedCommandAnnotation(annoPropStartTag = "hello")
public class Foo {
}
/* ExtendedCommandAnnotation.java */
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention( RetentionPolicy.RUNTIME )
public @interface ExtendedCommandAnnotation {
String annoPropUseTab() default "0";
String annoPropStartTag() default "";
String annoPropEndTag() default "";
}
/* Main.java */
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class Main {
public static void main(String[] args) {
doOriginalImplementation(); // Prints "hello"
doReflectionImplementation(); // Prints "hello"
}
public static void doOriginalImplementation() {
Foo foo = new Foo();
ExtendedCommandAnnotation e = foo.getClass().getAnnotation(ExtendedCommandAnnotation.class);
String startTag = e.annoPropStartTag();
System.out.println(startTag);
}
public static void doReflectionImplementation() {
Foo foo = new Foo();
Annotation[] annotations = foo.getClass().getAnnotations();
// or the statement below, depends on what you intent to do:
// Annotation[] annotations = foo.getClass().getDeclaredAnnotations();
Class classOfExtendedCommandAnnotation = null;
Annotation annotationOnClassFoo = null;
for (Annotation a : annotations) {
Class classA = a.annotationType();
if ("ExtendedCommandAnnotation".equals(classA.getName())) {
classOfExtendedCommandAnnotation = classA;
annotationOnClassFoo = a;
break;
}
}
Method methodAnnoPropStartTag = null;
if (classOfExtendedCommandAnnotation != null) {
try {
methodAnnoPropStartTag = classOfExtendedCommandAnnotation.getMethod("annoPropStartTag");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
if (methodAnnoPropStartTag != null) {
try {
String startTag = (String) methodAnnoPropStartTag.invoke(annotationOnClassFoo);
System.out.println(startTag);
} catch (ClassCastException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
}
在我的解决方案中,类ExtendedCommandAnnotation
不需要在编译时出现。但是,必须存在班级Foo
。可以稍微修改一下解决方案,以便类Foo
也不需要出现。