Annotation and exception [closed]

2019-08-22 15:27发布

问题:

I'm reading the error log file and I'm checking if error line refers to the annotation. I tried on the doc without results, but can the annotation (or a custom annotation) throw an exception?

Thanks a lot.

回答1:

Annotations are not executed, hence they can't throw an exception.



回答2:

Annotations can be processed in two ways:

  • at compile time: they actually result in different/additional byte code being written into class files
  • at run time: typically, some sort of framework checks for the presence of an annotation on a method/class/... to then run different code, depending if that specific annotation is in place or not

In other words: the annotation itself doesn't resemble to any real code, it is just a "marker". But of course, in order to do something useful (especially at runtime), there is probably some code that does something different when annotations are present. And of course, that code can throw exceptions. But in that case, you should receive a stack trace, and hopefully helpful messages.

From that point of view: the annotation itself can't throw an exception, because the annotation itself doesn't resemble something that can be "executed". Or to steal wording from the other answer by J-Alex: annotations can cause exceptions, but they can't be the "source".



回答3:

Annotation can be a CAUSE of the exception, but cannot throw it hence it's just a marker for an Annotation Processor.

This is a dummy example how an Annotation can be a cause of an Exception:

public class Main {

    @ValidNumber
    public String number = "1234X5";

    public static void main(String[] args) {
        new AnnotationProcessor().scan();
    }
}

class AnnotationProcessor {
    private String regex = "\\d+";

    void scan() {
        Main m = new Main();
        for (Field field : m.getClass().getDeclaredFields()) {
            ValidNumber annotation = field.getAnnotation(ValidNumber.class);
            if (annotation != null)
                process(m, field);
        }
    }

    void process(Object target, Field field) {
        try {
            Object o = field.get(target);
            if (!o.toString().matches(regex))
                throw new IllegalStateException("Wrong number in the class " + target);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface ValidNumber {
}

Output:

Exception in thread "main" java.lang.IllegalStateException: Wrong number in the class com.test.Main@5c3bd550
    at com.test.AnnotationProcessor.process(Main.java:32)
    at com.test.AnnotationProcessor.scan(Main.java:24)
    at com.test.Main.main(Main.java:12)

This is an example how to process annotation an RUNTIME.