Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Getting an instance of an annotation with default element values

Reply
Thread Tools

Getting an instance of an annotation with default element values

 
 
Tom Anderson
Guest
Posts: n/a
 
      05-10-2009
Right,

I have defined an annotation like so:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ParallelConfiguration {
public int numThreads() default 3;
}

Elsewhere in my code, i do something like this:

Class someClass;
ParallelConfiguration conf = someClass.getAnnotation(ParallelConfiguration.clas s);
int numThreads = conf.numThreads();

Obviously, if someClass lacks a ParallelConfiguration, this won't work. At
present, my code actually does:

Class someClass;
ParallelConfiguration conf = someClass.getAnnotation(ParallelConfiguration.clas s);
int numThreads;
if (conf != null) numThreads = conf.numThreads();
else numThreads = DEFAULT_NUMBER_OF_THREADS;

But this is really stupid. I already have a default for numThreads
defined, in the ParallelConfiguration annotation itself; defining another
default elsewhere is dreadful. I could refactor a little bit to make both
bits of code refer to the same constant:

public @interface ParallelConfiguration {
public static final int DEFAULT_NUM_THREADS = 3;

public int numThreads() default DEFAULT_NUM_THREADS;
}

if (conf != null) numThreads = conf.numThreads();
else numThreads = ParallelConfiguration.DEFAULT_NUM_THREADS;

And that's better, but it's still stupid: it's not making use of the fact
that the annotation has a natural way of expressing defaults. This comes
back to haunt me when i start to add more things to the annotation:

public @interface ParallelConfiguration {
public static final int DEFAULT_NUM_THREADS = 3;
public static final String DEFAULT_THREAD_NAME_PREFIX = "worker";

public int numThreads() default DEFAULT_NUM_THREADS;
public String threadNamePrefix() default DEFAULT_THREAD_NAME_PREFIX;
public int threadPriority() default Thread.NORM_PRIORITY;
}

When my client code starts to look really vile:

int numThreads;
String threadNamePrefix;
int threadPriority;
if (conf != null) {
numThreads = conf.numThreads();
threadNamePrefix = conf.threadNamePrefic();
threadPriority = conf.threadPriority();
}
else {
// all this just duplicates the default definitions!
numThreads = ParallelConfiguration.DEFAULT_NUM_THREADS;
threadNamePrefix = ParallelConfiguration.DEFAULT_THREAD_NAME_PREFIX;
threadPriority = Thread.NORM_PRIORITY;
}

What i really want to do is something like this:

if (conf == null) conf = getDefaultInstance(ParallelConfiguration.class);
int numThreads = conf.numThreads();
String threadNamePrefix = conf.threadNamePrefic();
int threadPriority = conf.threadPriority();

The problem is that i have no idea how to do the getDefaultInstance bit.
Is there a standard way to do this?

The best i've come up with is to apply some sort of trickery, like this:

public @interface ParallelConfiguration {

@ParallelConfiguration
public static class DefaultBearer {}

public static final ParallelConfiguration DEFAULT = DefaultBearer.class.getAnnotation(ParallelConfigur ation.class);

public int numThreads() default 3;
}

Which works (well, compiles, and looks like it should work), and does what
i want, but is pure evil. I could get rid of the DefaultBearer class by
applying the annotation to itself, but that doesn't exactly reduce the
level of evil!

Any thoughts?

tom

--
Can we fix it? Yes we can!
 
Reply With Quote
 
 
 
 
Tom Anderson
Guest
Posts: n/a
 
      05-10-2009
On Sun, 10 May 2009, Tom Anderson wrote:

> I could get rid of the DefaultBearer class by applying the annotation to
> itself, but that doesn't exactly reduce the level of evil!


Or not - that compiles, but dies with a NoClassDefFoundError when the JVM
tries to load the annotation class. Specifically, it seems constructs of
the form:

@Foo
public @interface Foo {
public Foo FOO = Foo.class.getAnnotation(Foo.class);
}

Won't work. Although this:

@Foo
public @interface Foo {
public Foo FOO = FooAccomplice.FOO;
}

class FooAccomplice {
public Foo FOO = Foo.class.getAnnotation(Foo.class);
}

Does. Huh. And you can even make the accomplice an inner class of the
annotation. I suppose that does make sense from a classloading point of
view, but it's still mildly baffling.

tom

--
Can we fix it? Yes we can!
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
read java Annotation field values from class mani Java 2 03-01-2012 06:00 PM
read java Annotation field values from class mani Java 1 03-01-2012 05:56 PM
Cyclic annotation element type Christopher Benson-Manica Java 1 03-16-2007 04:15 PM
[annotations][reflection] getting the annotation of the "super.method" Ingo R. Homann Java 0 07-26-2005 12:59 PM
Getting Annotation for a Return Type (Java 1.5 Beta) Raymond McCrae Java 2 03-03-2004 06:37 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57