Java notation.toString()忽略字符串属性中的双引号

Java notation.toString()忽略字符串属性中的双引号,java,reflection,annotations,Java,Reflection,Annotations,当注释字段是字符串时,如何使用双引号打印它的值? 例如: @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @interface MyAnnotation { String myField(); } @MyAnnotation(myField = "bla") public class Test { public static void main(String[] args) { for

当注释字段是字符串时,如何使用双引号打印它的值? 例如:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation {
    String myField();
}

@MyAnnotation(myField = "bla")
public class Test {

    public static void main(String[] args) {
        for (Annotation annotation : Test.class.getAnnotations()) {
            System.out.println(annotation);
        }
    }

}
上述代码生成:

@MyAnnotation(myField=bla)
如何更改它以生成
@MyAnnotation(myField=“bla”)

该界面不提供对特定注释的任何洞察。但我认为你可以做如下事情:

public static void main(String[] args) {
  for (Annotation annotation : Test.class.getAnnotations()) {
    if (annotation instanceof MyAnnotation) {
       ... then you can cast to that specific type ...
       ... and then access/print 
    }
}

通常情况下,应该避免使用Downcast进行此类检查,但我看不到不这样做就可以解决问题的方法。

反射是唯一的方法:

for (Annotation annotation : Test.class.getAnnotations()) {
    System.out.println(toString(annotation));
}

private String toString(Annotation annotation) throws InvocationTargetException, IllegalAccessException {
    Map<String, Object> paramValues = getParamValues(annotation);
    StringBuilder result = new StringBuilder("@")
            .append(annotation.annotationType().getSimpleName())
            .append("(");
    for (Map.Entry<String, Object> param : paramValues.entrySet()) {
        result.append(param.getKey()).append("=\"").append(param.getValue()).append("\", ");
    }
    result.delete(result.length() - 2, result.length());
    return result.append(")").toString();
}

private Map<String, Object> getParamValues(Annotation annotation) throws InvocationTargetException, IllegalAccessException {
        Map<String, Object> params = new HashMap<>();
        for (Method param : annotation.annotationType().getMethods()) {
            if (param.getDeclaringClass() == annotation.annotationType()) { //this filters out built-in methods, like hashCode etc
                params.put(param.getName(), param.invoke(annotation));
            }
        }
        return params;
}
for(注释:Test.class.getAnnotations()){
System.out.println(toString(annotation));
}
私有字符串toString(注释注释)抛出InvocationTargetException、IllegalAccessException{
Map paramValues=getParamValues(注释);
StringBuilder结果=新的StringBuilder(“@”)
.append(annotation.annotationType().getSimpleName())
.附加(“(”);
对于(Map.Entry参数:paramValues.entrySet()){
result.append(param.getKey()).append(“=\”).append(param.getValue()).append(“\”,”);
}
result.delete(result.length()-2,result.length());
返回result.append(“)”.toString();
}
私有映射getParamValues(注释注释)抛出InvocationTargetException、IllegalAccessException{
Map params=新的HashMap();
对于(方法参数:annotation.annotationType().getMethods()){
if(param.getDeclaringClass()==annotation.annotationType()){//这会过滤掉内置方法,如hashCode等
put(param.getName(),param.invoke(annotation));
}
}
返回参数;
}
对于任何类上的任何注释,这将精确地打印您所要求的内容(您只需查看如何打印非字符串属性)


但是。。。你为什么需要这个?

自己打印出来。@Boristeider听起来不错,但你怎么做?!注释界面不提供任何方式来访问进行此类打印所需的内部构件。那东西只能提供给你!您是否正在尝试重建源代码?你为什么要这么做?怎么打印有什么关系?这里你唯一能做的就是反射,这会很痛苦。@SotiriosDelimanolis我需要它,因为我正在运行时扩展和编译一个类,而该类不继承注释。我不能这样做,因为打印注释的方法不知道MyAnnotation或Test。然后我不知道如何帮助。除非您想使用反射来查看这些注释,并根据使用反射可以发现的内容进行“打印”。谢谢,Kaqao。真管用!我需要它,因为我在运行时扩展和编译一个类,而该类不继承注释。