From markus_keller at ch.ibm.com Mon Mar 3 08:29:42 2014 From: markus_keller at ch.ibm.com (Markus Keller) Date: Mon, 3 Mar 2014 17:29:42 +0100 Subject: ordering of annotated array brackets Message-ID: JLS8 10.2 says: "In a variable declaration (?8.3, ?8.4.1, ?9.3, ?14.14, ?14.20) except for a variable arity parameter, the array type of a variable is denoted by the array type that appears at the beginning of the declaration, followed by any bracket pairs that follow the variable's Identifier in the declarator." This was fine for Java < 8, where array dimension brackets were indistinguishable. But with type annotations, the order of annotated dimension brackets matters. Example: private @A int @B [] field @C []; In "1.8.0-b129", reflection says the type of "field" is "@A int @C [] @B []", and that totally makes sense. See also [1]. The paragraph should e.g. say: "[..] the array type of a variable is denoted by the element type at the beginning of the declaration, followed by any (potentially annotated) bracket pairs that follow the variable's Identifier in the declarator, followed by any (potentially annotated) bracket pairs of the array type at the beginning of the declaration." The ordering of consecutive array dimension brackets is currently also undefined by the spec. There's just an informal example in 9.7.4 (which is good; it's just not a spec). Regards, Markus [1] Executable snippet to test reflection: import java.lang.annotation.*; import java.lang.reflect.*; import java.util.stream.*; @Target(ElementType.TYPE_USE) @Retention(RetentionPolicy.RUNTIME) @interface A {} @Target(ElementType.TYPE_USE) @Retention(RetentionPolicy.RUNTIME) @interface B {} @Target(ElementType.TYPE_USE) @Retention(RetentionPolicy.RUNTIME) @interface C {} public class Snippet { private @A int @B [] field @C []; private @A int @C [] @B [] fieldNormal; private @A int @B [] fieldBase, fieldExtra @C []; public static void main(String[] args) throws Exception { printField("field"); printField("fieldNormal"); printField("fieldBase"); printField("fieldExtra"); } private static void printField(String name) throws NoSuchFieldException { System.out.printf("%-12s %s\n", name + ":", toString(Snippet.class.getDeclaredField(name).getAnnotatedType())); } private static String toString(AnnotatedType annotatedType) { StringBuilder sb = new StringBuilder(); while (annotatedType instanceof AnnotatedArrayType) { sb.append(" ").append(toString(annotatedType.getAnnotations())).append("[]"); annotatedType = ((AnnotatedArrayType) annotatedType).getAnnotatedGenericComponentType(); } Type type = annotatedType.getType(); sb.insert(0, type.toString()); sb.insert(0, toString(annotatedType.getAnnotations())); return sb.toString(); } private static String toString(Annotation[] annotations) { return Stream.of(annotations).map(Snippet::toSimpleString). collect(Collectors.joining(" ", "", " ")); } public static String toSimpleString(Annotation a) { return "@" + a.annotationType().getSimpleName(); } } From dieter.kleinrath at gmail.com Sat Mar 15 11:57:29 2014 From: dieter.kleinrath at gmail.com (Dieter Kleinrath) Date: Sat, 15 Mar 2014 12:57:29 +0100 Subject: Are annotations on parameter types supported in lambda expressions? Message-ID: Hello! I'm not sure, if this is the right place to ask this question, or if it would be better to ask the developers of JSR 335 (Project Lambda). The JSR 308 Specification is not very specific about whether Type Annotations should also be allowed on the type parameters of lambda expressions or not. But if I read it correctly, I guess code like the following should be ok (where MyTypeAnnotation is an Annotation with ElementType#TYPE_USE): Consumer c = (@MyTypeAnnotation String p) -> System.out.println(p); But the current JDK 8 (b132) javac compiler does not store the information of parameter type annotations in the generated class files (the same is true for the current Eclipse JDT compiler). I tested this by trying to get the Annotation at runtime with Method#getAnnotatedParameterTypes() and by reading the class file with the latest ASM build (that already supports Type Annotations). So I wanted to ask if you can confirm, that parameter Type Annotations should/will be supported for lambda expressions? Also, do you think, that this feature has not yet been implemented but is on the TODO list, or if this should already be reported as a bug to the Lambda developers? Thanks for your help, Dieter PS.: On a side note: parameter names of lambda expressions are currently also not stored in the class files, if one compiles with javac -parameters... From alex.buckley at oracle.com Mon Mar 17 19:48:14 2014 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 17 Mar 2014 12:48:14 -0700 Subject: Are annotations on parameter types supported in lambda expressions? In-Reply-To: References: Message-ID: <5327517E.8090000@oracle.com> Hi Dieter, On 3/15/2014 4:57 AM, Dieter Kleinrath wrote: > I'm not sure, if this is the right place to ask this question, or if it > would be better to ask the developers of JSR 335 (Project Lambda). type-annotations-spec-comments is the right place to ask about the design intent of type annotations. > The JSR 308 Specification is not very specific about whether Type > Annotations should also be allowed on the type parameters of lambda > expressions or not. But if I read it correctly, I guess code like the > following should be ok (where MyTypeAnnotation is an Annotation > with ElementType#TYPE_USE): > > Consumer c = (@MyTypeAnnotation String p) -> System.out.println(p); You speak of "type parameters of lambda expressions" but lambda expressions are not generic so they cannot declare type parameters. As to the types of formal parameters of lambda expressions, it has been legal to annotate them for some time [1]. See JLS8 9.6.4.1, 9.7.4, and 4.11. [1] http://mail.openjdk.java.net/pipermail/type-annotations-spec-experts/2012-December/000044.html > But the current JDK 8 (b132) javac compiler does not store the information > of parameter type annotations in the generated class files (the same is > true for the current Eclipse JDT compiler). I tested this by trying to get > the Annotation at runtime with Method#getAnnotatedParameterTypes() and by > reading the class file with the latest ASM build (that already supports > Type Annotations). javac emits the correct Runtime[In]VisibleTypeAnnotations attribute for annotations on the types of formal parameters of a lambda expression. The attribute appears on the private method generated for a lambda expression, so you need to run javap with -p to see it. However, there are known bugs in the emission of, and especially the reflection of, annotations on types of formal parameters. See https://bugs.openjdk.java.net/browse/JDK-8027181. > PS.: On a side note: parameter names of lambda expressions are currently > also not stored in the class files, if one compiles with javac > -parameters... I confirm this is a javac bug; thanks, I'll report it. Alex From srikanth_sankaran at in.ibm.com Tue Mar 18 02:27:02 2014 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Tue, 18 Mar 2014 07:57:02 +0530 Subject: Are annotations on parameter types supported in lambda expressions? In-Reply-To: References: Message-ID: Thanks for the report, I have raised https://bugs.eclipse.org/bugs/show_bug.cgi?id=430571 against the eclipse compiler. Srikanth From dieter.kleinrath at gmail.com Tue Mar 18 10:50:30 2014 From: dieter.kleinrath at gmail.com (Dieter Kleinrath) Date: Tue, 18 Mar 2014 11:50:30 +0100 Subject: Are annotations on parameter types supported in lambda expressions? In-Reply-To: <5327517E.8090000@oracle.com> References: <5327517E.8090000@oracle.com> Message-ID: Hello Alex, thank you very much for your explanation. > You speak of "type parameters of lambda expressions" but lambda > expressions are not generic so they cannot declare type parameters. As to > the types of formal parameters of lambda expressions, it has been legal to > annotate them for some time [1]. See JLS8 9.6.4.1, 9.7.4, and 4.11. > > [1] http://mail.openjdk.java.net/pipermail/type-annotations- > spec-experts/2012-December/000044.html > > Sorry, but I expressed myself incorrectly: of course I didn't mean the annotations of "type parameters of lambda expressions" (as in generics), instead I meant annotations of the type of a formal parameter. But with the help of your answer I was indeed able to find the type annotations on formal parameters of lambda expressions in the Runtime VisibleTypeAnnotations attribute of the class file when compiling with javac. It turned out I messed my own tests up a bit and the bug is only relevant for the Eclipse compiler. The reason I'm not able to receive the type annotation using reflection is certainly related to https://bugs.openjdk.java.net/browse/JDK-8027181. Thanks again, Dieter From alex.buckley at oracle.com Wed Mar 19 18:09:22 2014 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 19 Mar 2014 11:09:22 -0700 Subject: Are annotations on parameter types supported in lambda expressions? In-Reply-To: References: Message-ID: <5329DD52.6090601@oracle.com> On 3/17/2014 7:27 PM, Srikanth S Adayapalam wrote: > Thanks for the report, I have raised > https://bugs.eclipse.org/bugs/show_bug.cgi?id=430571 > against the eclipse compiler. The equivalent javac bug re: MethodParameters for a private method representing a lambda expression is https://bugs.openjdk.java.net/browse/JDK-8037546. Alex