37

I have stumbled upon a strange behavior that I don't understand.

I have to cast a String to a generic and it's producing a warning.

Type safety : Unchecked cast from String to T
  • If I add @SuppressWarnings("unchecked")above the method declaration it works fine.

  • If I add it above the assignment it produces a compiler error in eclipse.

This works fine.

@SuppressWarnings("unchecked")
public <T> T search(final String query){
 T returnValue = null;
 ...
 if(returnValue instanceof String){
  returnValue = (T) collection.getString(attrName);
 }

This don't work fine.

public <T> T search(final String query){
 T returnValue = null;
 ...
 if(returnValue instanceof String){
  @SuppressWarnings("unchecked") // Compiler error: "returnValue cannot be resolved to a type"
  returnValue = (T) collection.getString(attrName);
 }

Any idea what's causing the discrepancy between the two methods of suppressing the warning?

1 Answers1

55

You can't have annotation on arbitrary expressions (yet? Maybe they'll add it later on).

You can however have annotations on local variable declarations.

So what the compiler tries to do here is to interpret returnValue as a type (as that's the only thing that can follow an annotation inside a method body) and fails.

Putting the annotation at the declaration of returnValue does not help in this case. You can however create a new local variable where you perform the cast in the initializer and annotate that.

@SuppressWarnings("unchecked")
T string = (T) collection.getString(attrName);
returnValue = string;
henko
  • 763
  • 7
  • 16
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • 1
    Came here, because I did not understand the error _"Syntax error on token 'results', VariableDeclaratorId expected after this token"_ in Eclipse. Your explanation what the compiler tries and why it fails is great! Just adding this comment, in case anybody else searches for this syntax error. – user1438038 Sep 29 '17 at 09:12