Annotation syntax in the JLS?

T

Tom Anderson

Hi all,

Stupid question - where's the definition of the syntax, at the lexical
level, of annotations in the JLS? I mean the application of annotations,
specifically to classes - the rules that make this:

@Foo
public class Bar {}

legal.

There's nothing in chapter 3 about them, and nothing in the relevant bits
of chapter 9 about syntax.

I came across something weird the other day, where the Eclipse and Sun
compilers seem to differ over whether a comma is permitted after the last
item in a literal array of classes that's used as an annotation value.
Normally, java permits the bonus comma after the last item:

int[] a = new int[] {1, 2, 3,}; // legal

But javac seemed to be rejecting this:

import org.junit.Suite;

@Suite.SuiteClasses({
Foo.class,
Bar.class, // illegal!
})
public class MySuite {}

I'm a bit puzzled over the lexical status of the structure comprising the
curly brackets and their contents (the comma, and why a "new Class[]"
isn't needed), and would like to see what the letter of the law is, but
can't find it.

tom
 
A

Arne Vajhøj

Tom said:
Hi all,

Stupid question - where's the definition of the syntax, at the lexical
level, of annotations in the JLS? I mean the application of annotations,
specifically to classes - the rules that make this:

@Foo
public class Bar {}

legal.

There's nothing in chapter 3 about them, and nothing in the relevant
bits of chapter 9 about syntax.

I came across something weird the other day, where the Eclipse and Sun
compilers seem to differ over whether a comma is permitted after the
last item in a literal array of classes that's used as an annotation
value. Normally, java permits the bonus comma after the last item:

int[] a = new int[] {1, 2, 3,}; // legal

But javac seemed to be rejecting this:

import org.junit.Suite;

@Suite.SuiteClasses({
Foo.class,
Bar.class, // illegal!
})
public class MySuite {}

I'm a bit puzzled over the lexical status of the structure comprising
the curly brackets and their contents (the comma, and why a "new
Class[]" isn't needed), and would like to see what the letter of the law
is, but can't find it.

Section 9.7 has:

NormalAnnotation:
@ TypeName ( ElementValuePairsopt )

ElementValuePairs:
ElementValuePair
ElementValuePairs , ElementValuePair

ElementValuePair:
Identifier = ElementValue

ElementValue:
ConditionalExpression
Annotation
ElementValueArrayInitializer

ElementValueArrayInitializer:
{ ElementValuesopt ,opt }

ElementValues:
ElementValue
ElementValues , ElementValue

Grammar is not be strong side but I assume you code is
a single ElementValuePair where Identifier is default
and ElementValue is an ElementValueArrayInitializer.

Arne
 
T

Tom Anderson

Tom said:
Stupid question - where's the definition of the syntax, at the lexical
level, of annotations in the JLS? I mean the application of annotations,
specifically to classes - the rules that make this:

@Foo
public class Bar {}

legal.

There's nothing in chapter 3 about them, and nothing in the relevant bits
of chapter 9 about syntax.

I came across something weird the other day, where the Eclipse and Sun
compilers seem to differ over whether a comma is permitted after the last
item in a literal array of classes that's used as an annotation value.
Normally, java permits the bonus comma after the last item:

int[] a = new int[] {1, 2, 3,}; // legal

But javac seemed to be rejecting this:

import org.junit.Suite;

@Suite.SuiteClasses({
Foo.class,
Bar.class, // illegal!
})
public class MySuite {}

I'm a bit puzzled over the lexical status of the structure comprising the
curly brackets and their contents (the comma, and why a "new Class[]" isn't
needed), and would like to see what the letter of the law is, but can't
find it.

Section 9.7 has:

NormalAnnotation:
@ TypeName ( ElementValuePairsopt )

ElementValuePairs:
ElementValuePair
ElementValuePairs , ElementValuePair

ElementValuePair:
Identifier = ElementValue

ElementValue:
ConditionalExpression
Annotation
ElementValueArrayInitializer

ElementValueArrayInitializer:
{ ElementValuesopt ,opt }

ElementValues:
ElementValue
ElementValues , ElementValue

Aha, yes, thank you! Not sure how i missed that.
Grammar is not be strong side but I assume you code is a single
ElementValuePair where Identifier is default and ElementValue is an
ElementValueArrayInitializer.

Indeed. And the production for ElementValueArrayInitializer does admit a
trailing comma: the production for ElementValues doesn't, but
ElementValueArrayInitializer has that ,opt in it.

Or at least i think it does. The typesetting in the HTML there is a bit
wacky - the comma in question is set as part of the opt subscript, rather
than at the same level as the ElementValues, but i *think* that's a
mistake; chapter 2, which defines the grammar notation, doesn't give any
meaning to a comma-separated double opt subscript, so i assume it can't
actually be that.

Anyway, it's striking that the spec defines an array initializer syntax
just for annotations, rather than reusing the one defined earlier for
actual arrays. I wonder why? I notice that the way it's done lets
annotation arrays include other annotations, which normal arrays, i think,
don't. Like this:

@Foo({@Bar, @Baz, @Qux})

I don't know what that means, though.

tom
 
J

Joshua Cranmer

Tom said:
@Foo({@Bar, @Baz, @Qux})

I don't know what that means, though.

The annotation @Foo containing a value which is an array of annotations,
specifically @Bar, @Baz and @Qux.

A better example (one that I've actually used):
@Options({
@Option(name="tabWidth", type=int.class, def="8"),
@Option(name="incWidth", type=int.class, def="4"),
@Option(name="lineWidth", type=int.class, def="80")
})
 
T

Tom Anderson

The annotation @Foo containing a value which is an array of annotations,
specifically @Bar, @Baz and @Qux.

A better example (one that I've actually used):
@Options({
@Option(name="tabWidth", type=int.class, def="8"),
@Option(name="incWidth", type=int.class, def="4"),
@Option(name="lineWidth", type=int.class, def="80")
})

Ahaa, of course, thank you. I was being rather dense and failing to make
the connection to annotations which have values (despite the fact that i'd
already written one!). Your example makes excellent sense - you're not
allowed to have multiple annotations of the same type on a class, so you
make a container annotation to hold them.

The only annotations i really use are the JUnit ones and SuppressWarnings
(with only the "unchecked" and "serial" values). I don't do EJB or JPA,
for instance, where i understand they get more play, and perhaps because i
haven't seen them in action, i've never written any of my own. Hence, i'm
really quite ignorant about them.

tom
 
M

Mike Schilling

Tom said:
The only annotations i really use are the JUnit ones and
SuppressWarnings (with only the "unchecked" and "serial" values). I
don't do EJB or JPA, for instance, where i understand they get more
play, and perhaps because i haven't seen them in action, i've never
written any of my own. Hence, i'm really quite ignorant about them.

Web services too; some containers allow you to simply annotate a class
as a service and methods as operations, and they will generate all the
plumbing to serialize/deserialize the XML as well as the WSDL.
 
A

Arne Vajhøj

Mike said:
Web services too; some containers allow you to simply annotate a class
as a service and methods as operations, and they will generate all the
plumbing to serialize/deserialize the XML as well as the WSDL.

JAXB can use annotations (JAXB is frequently used in some
of the stuff already mentioned, but it can also be used standalone).

AspectJ can use annotations as well.

I believe that JSF 2.0 and Servlet 3.0 are expected to use
annotations.

Arne
 
A

Arne Vajhøj

Tom said:
Tom said:
Stupid question - where's the definition of the syntax, at the
lexical level, of annotations in the JLS? I mean the application of
annotations, specifically to classes - the rules that make this:

@Foo
public class Bar {}

legal.

There's nothing in chapter 3 about them, and nothing in the relevant
bits of chapter 9 about syntax.

I came across something weird the other day, where the Eclipse and
Sun compilers seem to differ over whether a comma is permitted after
the last item in a literal array of classes that's used as an
annotation value. Normally, java permits the bonus comma after the
last item:

int[] a = new int[] {1, 2, 3,}; // legal

But javac seemed to be rejecting this:

import org.junit.Suite;

@Suite.SuiteClasses({
Foo.class,
Bar.class, // illegal!
})
public class MySuite {}

I'm a bit puzzled over the lexical status of the structure comprising
the curly brackets and their contents (the comma, and why a "new
Class[]" isn't needed), and would like to see what the letter of the
law is, but can't find it.

Section 9.7 has:

NormalAnnotation:
@ TypeName ( ElementValuePairsopt )

ElementValuePairs:
ElementValuePair
ElementValuePairs , ElementValuePair

ElementValuePair:
Identifier = ElementValue

ElementValue:
ConditionalExpression
Annotation
ElementValueArrayInitializer

ElementValueArrayInitializer:
{ ElementValuesopt ,opt }

ElementValues:
ElementValue
ElementValues , ElementValue

Aha, yes, thank you! Not sure how i missed that.
Grammar is not be strong side but I assume you code is a single
ElementValuePair where Identifier is default and ElementValue is an
ElementValueArrayInitializer.

Indeed. And the production for ElementValueArrayInitializer does admit a
trailing comma: the production for ElementValues doesn't, but
ElementValueArrayInitializer has that ,opt in it.

Or at least i think it does. The typesetting in the HTML there is a bit
wacky - the comma in question is set as part of the opt subscript,
rather than at the same level as the ElementValues, but i *think* that's
a mistake; chapter 2, which defines the grammar notation, doesn't give
any meaning to a comma-separated double opt subscript, so i assume it
can't actually be that.

The PDF is a bit more readable.

I think that the opt subscript means that the preceding item is
optional.

So according to the grammar your trailing comma should be legal.

And indeed javac gives an error on the construct, but the Eclipse
compiler accepts it.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top