Home > Uncategorized > Hack of the day: Get a method-annotation’s default value

Hack of the day: Get a method-annotation’s default value

So you have an annotation like this:

@Inherited
@Documented
@InterceptorBinding
@Retention(RUNTIME)
@Target({ METHOD, TYPE, FIELD })
public @interface Logged {

	@Nonbinding
	String value() default "debug";

	@Nonbinding
	String detailValue() default "trace";

}

But the source code is not under your control, so you can’t refactor it to use a public constant. How will you get any annotation method’s default value?
You could do it like this:

private String badWay() {
	final Method meth = Logged.class.getMethod("detailValue");
	final Logged annotation = meth.getAnnotation(Logged.class);
	return Level.valueOf(annotation.value());
}

But then, if someone from the outside refactored it and renamed the method, your compiler won’t notice and it will break at runtime, which is bad.
Here’s a way to perform the task with some introspection, given the annotation can be used on methods:

Logged defaultLogged; //lazily initialized, as reflection is slow

@Logged // annotation with default log level
private String defaultAnnotationDetailLogLevel() {
        if(defaultLogged == null}{
            class Local {};
            final Method meth = Local.class.getEnclosingMethod(); // this method
            defaultLogged = meth.getAnnotation(Logged.class);
        }
        return defaultLogged.detailValue();
}

In case the annotation will be changed to use any other method name, your compiler will notice immediately and you can fix the broken code before it slips through testing and hits production. Nifty!

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: