-3

Why isn't this variable considered to be final? This code does not compile, I would say it is a bug or at least is strange..

public class QualifierConfiguration {
    public static final String RANK_CALCULATOR = RankCalculatorImpl.class.getName();
}


public class Implementation{
    private final RankCalculator rankCalculator;
    public Implementation(@Qualifier(QualifierConfiguration.RANK_CALCULATOR) RankCalculator rankCalculator){
        this.rankCalculator = rankCalculator;
    }
}

and not even this does not work

public class QualifierConfiguration {
    public static final String RANK_CALCULATOR = getValue();
    private static String getValue(){
        return "string";
    }
}
Mike
  • 279
  • 2
  • 11

2 Answers2

1

A final variable is not necessarily a compile-time constant:

4.12.4. final Variables

A variable can be declared final. A final variable may only be assigned to once.

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).

RankCalculatorImpl.class.getName() is not a constant expression, neither is getValue().

Note that for annotation having a Class value, class literals like RankCalculatorImpl.class are allowed, due to the specific rules for annotations, but they still don’t make compile-time constants (the same applies to enum constant references). For primitive and String values, the specification clearly mandates constant expressions for the annotation values:

An element type T is commensurate with an element value V if and only if one of the following is true:

  • T is not an array type, and the type of V is assignment compatible (§5.2) with T, and:

    • If T is a primitive type or String, then V is a constant expression (§15.28).
    • If T is Class or an invocation of Class (§4.5), then V is a class literal (§15.8.2).
    • If T is an enum type (§8.9), then V is an enum constant (§8.9.1).
    • V is not null.

So here, you have no other choice than specifying the actual qualified name as string literal:

public static final String RANK_CALCULATOR = "actual.package.name.RankCalculatorImpl";
Community
  • 1
  • 1
Holger
  • 285,553
  • 42
  • 434
  • 765
0

You have to pass a constant expression to an annotation. So it has to be constant during compile time. You can get more info about compile time constants here. Similar SO question here.

The exception you get from this is: The value for annotation attribute Qualifier.value must be a constant expression

Sandeep B
  • 765
  • 1
  • 6
  • 19