This discussion is archived
6 Replies Latest reply: Sep 18, 2010 1:27 PM by 843793 RSS

Why annotation is allowed for annotation method's return type

843793 Newbie
Currently Being Moderated
What's the point of allowing annotation as the return type of an annotation method
Here is the example:
@interface A {    
    T value();
}

@interface T {
}
But here if you don't have the default value for value() whenever you use this annotation you have to set the same constant value for it: @A(@T)
If you have default value default would be alway a constant : T value() default @T;
Since you can't subclass type T, always the same annotation has to be set for the value() method.
User has no option for setting this method. It would always return the same value so what's the point of allowing it at first place.

Am I missing something? Is there any possible case that using annotation as return type would make sense?

Thank you

Edited by: danial.farid on Sep 14, 2010 9:38 AM
  • 1. Re: Why annotation is allowed for annotation method's return type
    608410 Newbie
    Currently Being Moderated
    Your question mostly arises because you are using a trivial definition of @T. With a more complex @T this feature allows structured data.

    A common use case is where you have an annotation that in some (but not all) instances you want to apply multiple times to the same program element. The language doesn't let you do that so the solution is to provide a 'collection' annotation. best shown with an example
    @interface Author {
        String name();
        String org();
    }
    
    
    @interface Authors {
        Author[] value();
    }
    which means you can then do either
    @Author(name="bruce", org="disorg") 
    class MyClass {}
    or
    @Authors({
        @Author(name="bruce", org="disorg") ,
        @Author(name="danial", org="datorg") 
    })
    class OurClass {}
    A related issue is that default value specified does not have to be exactly the same as the meaning of the default value. (syntax vs semantics) For example an annotation targeting methods might have a name member with a default of "", but the actual interpretation of that is if the name is not specified, then the name is in some way inferred from the method name. E.g.
    @interface Property {
        /** the name of the property. If not specified then the name is inferred from the 
             target method's name by removing any "get" or "set" prefix and lowercasing the 
            1st remaining character 
          */
        String name() default "";
    }
  • 2. Re: Why annotation is allowed for annotation method's return type
    843793 Newbie
    Currently Being Moderated
    Other examples would be JPA's annotation @NamedQueries for specifying multiple queries at an entity or Bean Validation's notation for specifying multiple constraints of the same type at an element:
    @Pattern.List({
        @Pattern(regexp = "^[A-Z0-9-]+$"),
        @Pattern(regexp = "...")
    })
    private String orderNo;
    The Bean Validation specification recommends that each constraint annotation defines an inner @List annotation for this purpose.

    One thing I find a bit disappointing is that it is not possible to specify a generic List annotation which has an array of the type java.lang.annotation.Annotation (which each Java annotation type implicitely extends) as value. Trying to do so yields in a compiler error.

    Bruce, do you have an idea why this restriction exists? Maybe this could be removed in a future Java version :-)
  • 3. Re: Why annotation is allowed for annotation method's return type
    608410 Newbie
    Currently Being Moderated
    I am not quite sure what you mean.

    When you say
    generic List
    do you mean 'generic' generically, or specifically a java.util.List<T> where generic means F-bounded type polymorphism as defined in JSR-14 and as implemented in JDK 5.

    If you got a compiler error you probably had some code. can you post an example to help us understand what you mean?

    Bruce
  • 4. Re: Why annotation is allowed for annotation method's return type
    843793 Newbie
    Currently Being Moderated
    I meant "generic" generically :-)

    I'd like to be able to define an annotation with an array-typed value, that can contain any concrete annotation (which should not generally be impossible, as each annotation type extends java.lang.annotation.Annotation):
    @interface List {
        java.lang.annotation.Annotation[] value();   
    }
    Currently this is rejected by the compiler. The Bean Validation spec therefore recommends that each constraint type also provides its own List annotation which takes an array of that constraint. The following example is taken from BV's @Pattern constraint:
    @interface List {
        Pattern[] value();
    }
    If the first listing would be allowed, such dedicated list constraints were not required.

    Gunnar
  • 5. Re: Why annotation is allowed for annotation method's return type
    608410 Newbie
    Currently Being Moderated
    When annotations were designed, many language features that could possibly be applied to annotations (inheritance, generics, [safe circular references|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6264216] ...) were explicitly disallowed to minimize unforeseen detrimental interactions. It was very conservative. What this means is that while the annotation feature can feel somewhat crippled, it is not actually broken - the latter being a risk in the absence of the conservative decisions.

    If you want to change that, you really need to provide some proof of concept. Maybe you could hack the language (on say the kijaro project) and see how you get on.
    Bruce
  • 6. Re: Why annotation is allowed for annotation method's return type
    843793 Newbie
    Currently Being Moderated
    Thanks for your answer. I was not aware of Kijaro and will have a look into it. I think one thing to consider when allowing the feature I described would probably be the circularity issue you mentioned.

    Gunnar