Type annotations don't look very Java-like

Timo Kinnunen timo.kinnunen at gmail.com
Thu Sep 19 09:28:30 PDT 2013


Hi,

A small correction to case 2 presented in this:

"I want to annotate both of the bridge-methods with identical annotations
for consistency.

1) The first parameter List I want to have @Important on the parameter only.

2) For the other parameters I want one of them to have the annotation
@Important on both parameter and type and the other one have @Important on
type only.

Neither of these are possible."

It seems I was wrong about case 2 and it is possible after all. Here's what
the method looks like:

public final class List {
  public <java_awt_List extends java.awt.List> void genericBridge(
          List this,
          java.util. at Important List container,
          @Important java_awt_List viewer) {
    // TODO
  }
}
This produces the following javap -v -p -s output that satisfies the
requirement for case 2:

    RuntimeVisibleTypeAnnotations:
      0: #24(): METHOD_FORMAL_PARAMETER, param_index=1
      1: #24(): METHOD_FORMAL_PARAMETER, param_index=0
    RuntimeVisibleParameterAnnotations:
      parameter 0:
      parameter 1:
        0: #24()


Is this working as designed or a bit of generics type programming?




On Thu, Sep 19, 2013 at 6:47 AM, Timo Kinnunen <timo.kinnunen at gmail.com>wrote:

> Hi,
>
> First, please correct me if I'm wrong, but it's my understanding that in
> Java 8 I be able to express
>
> 1) an annotation on a parameter ONLY
> 2) an annotation on a parameter and its type BOTH
> 3) an annotation on the type of a parameter ONLY
>
> and that each of these be distinguishable from the others, for annotation
> processing purposes, for example.
>
> Assuming the above, it strikes me that the changed grammar in addition to
> not looking very Java-like is also not expressive enough for the cases 1,
> 2, 3 above. Suppose I'm writing my magnum opus, a class to solve the
> problem of two lists in the standard library, the List:
>
> public final class List {
>   public static void bridge(List manager, java.util.List container,
> java.awt.List viewer) {
>     manager.bridge(container, viewer);
>   }
>   public void bridge(List this, java.util.List container, java.awt.List
> viewer) {
>     // TODO
>   }
> }
> @Retention(value = RetentionPolicy.RUNTIME)
> @Target({ElementType.TYPE_USE, ElementType.PARAMETER})
> public @interface Important {
> }
> I want to annotate both of the bridge-methods with identical annotations
> for consistency.
>
> 1) The first parameter List I want to have @Important on the parameter
> only.
>
> 2) For the other parameters I want one of them to have the annotation
> @Important on both parameter and type and the other one have @Important on
> type only.
>
> Neither of these are possible.
>
> The case 1 is not possible for two reasons. First because there is no
> modifier that can make { TYPE_USE, PARAMETER } be treated as { PARAMETER }.
> Second because a receiver can't be annotated with a parameter annotation,
> unlike its static counterpart. This forces an inconsistency onto this class
> design.
>
> The case 2 is not possible because it's not possible to express the
> difference. Annotating one parameter as @Important java.util.List and the
> other as java.awt. at Important List is not allowed. The grammar can't
> express the case where the verbose modifier-modifier was used to make {
> TYPE_USE, PARAMETER } be treated as { TYPE_USE } when the type is a
> fully-qualified name rather than a simple name. In other words, there is no
> way to write java.util. at Important java.util.List. Thankfully, one might
> say. Or mercifully.
>
> Interestingly, it is possible and required to write @Important
> java.util.List if @Important doesn't have TYPE_USE. Which means adding
> TYPE_USE to an existing annotation in a library can cause compile errors
> when Java 7 code switches to compiling against a Java 8 version of the
> library.
>
> I think some other mechanism is needed to put annotations on their types
> because I don't think these grammar changes are very well suited for
> that at all.
>
>
>
>
>
>
>
> On Thu, Sep 19, 2013 at 1:27 AM, Alex Buckley <alex.buckley at oracle.com>wrote:
>
>> David,
>>
>> It looks like there is a problem with how NetBeans handles annotations on
>> type names. I confess to not knowing which NetBeans engineer is working on
>> type annotations, so please inform them of the problem below.
>>
>> Timo,
>>
>>
>> On 9/18/2013 12:01 PM, Timo Kinnunen wrote:
>>
>>> Alex, there might be bugs or unimplemented changes, but trying it out in
>>> the latest NetBeans IDE 4.7 Beta, JDK 1.8.0-ea-b106 and the annotation
>>> @Regarding defined like this:
>>>
>>> @Retention(value = RetentionPolicy.RUNTIME)
>>> @Target(value = {ElementType.TYPE_USE, ElementType.PARAMETER,
>>> ElementType.FIELD, ElementType.LOCAL_VARIABLE})
>>> @interface Regarding { }
>>>
>>> Then as seen in the Trees (NetBeans development) view, right now you do
>>> have to write “com.somecompany.**AnnotationTestBed.” in front of the
>>> annotation to modify the modifier into becoming an annotated type
>>> instead.
>>> Specifically, instead of 1xMODIFIER, 1xIDENTIFIER there will be
>>> 0xMODIFIER,
>>> 1xANNOTATED_TYPE.
>>>
>>> I don’t know where this change in semantics comes from or what its
>>> meaning
>>> is, but I can see that it’s there. And as long as it is there, it can
>>> become requirement for using some functionality in any tool that can
>>> detect
>>> its presence.
>>>
>>
>> I'm on JDK 1.8.0-ea-b106. Here's a simplified test case:
>>
>> --
>> import java.lang.annotation.*;
>>
>> @Retention(RetentionPolicy.**RUNTIME)
>> @Target({ElementType.**PARAMETER})
>> @interface Regarding { }
>>
>> public class C {
>>   void m(@Regarding Object oldOne) {}
>> }
>> --
>>
>> javac will emit C.class with a RuntimeVisibleParameterAnnotat**ions
>> attribute for the 'm' method, just as it did in JDK7.
>>
>> Then, if you add ElementType.TYPE_USE to the @Target value:
>>
>> @Target({ElementType.TYPE_USE, ElementType.PARAMETER})
>>
>> and recompile, javac will emit C.class with a second attribute,
>> RuntimeVisibleTypeAnnotations, for the 'm' method. There are no surprises
>> here, and no need for qualified type names.
>>
>> If you really want to write "java.lang. at Regarding Object oldOne", you
>> can, and it's compiled correctly to just RuntimeVisibleTypeAnnotations - no
>> RuntimeVisibleParameterAnnotat**ions in sight. But you don't have to.
>>
>> Alex
>>
>
>
>
> --
> Have a nice day,
> Timo Kinnunen
>



-- 
Have a nice day,
Timo Kinnunen
+358445405900, +37258352396


More information about the type-annotations-spec-comments mailing list