Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java annotations: at variable initialization, but not assignment?

I've been having trouble understanding where exactly an annotation has to or can be placed.

The class with this method compiles, but gives a warning "unchecked":

<B extends BitSet> void doStuff(LinkedList<B> list) {
    B board = list.getFirst();
    B cloneBoard;
    cloneBoard = (B) board.clone(); //unchecked
}

This compiles without warning:

<B extends BitSet> void doStuff(LinkedList<B> list) {
    B board = list.getFirst();

    @SuppressWarnings("unchecked")
    B cloneBoard = (B) board.clone();
}

This doesn't compile but marks cloneBoard with an error:

<B extends BitSet> void doStuff(LinkedList<B> list) {
    B board = list.getFirst();
    B cloneBoard;

    @SuppressWarnings("unchecked")
    cloneBoard = (B) board.clone(); // cloneBoard cannot be resolved to a type;
                                    // VariableDeclaratorID expected
}

In the Sun tutorial on annotations, I couldn't find an answer as to why this is: http://docs.oracle.com/javase/tutorial/java/javaOO/annotations.html.

The grammar definition didn't help me either, since I'm not quite sure I understand it correctly: http://java.sun.com/docs/books/jls/third_edition/html/syntax.html#18.1

It seems to me that what's the problem here is that annotations can be specifically used for variables, but only when they are declared; any later assignment will not be covered by the annotation. Is this correct? Is there a more elegant solution than suppressing unchecked warnings for the whole method?

like image 334
G. Bach Avatar asked Dec 08 '11 03:12

G. Bach


2 Answers

From Java Language Specification - Interfaces > Annotation

Annotations may be used as modifiers in any declaration, whether package, class, interface, field, method, parameter, constructor, or local variable..

It can only use in a declaration.

like image 51
Rangi Lin Avatar answered Oct 20 '22 01:10

Rangi Lin


An annotation is part of a declaration; just as you can't write Object obj except at the point where obj is declared, nor final obj except as final Object obj, so too is @Deprecated obj forbidden.

As for elegance — ideally your methods should not be very long and complicated, anyway, but if you do find that you'd like to mark a specific assignment with this annotation, you can always make use of a simple wrapper method:

@SuppressWarnings("unchecked")
private static <T extends ClassThatDeclaresCloneAsPublic> T cloneObj(T obj)
    { return (T) obj.clone(); }

(Though in this specific case, I suppose you could write cloneBoard = board.getClass().cast(board.clone()); and dispense with the annotation altogether, if you wanted.)

like image 42
ruakh Avatar answered Oct 20 '22 01:10

ruakh