【问题标题】:Class final variable is not final [duplicate]类最终变量不是最终的[重复]
【发布时间】:2017-05-22 20:34:24
【问题描述】:

为什么这个变量不被认为是最终的?这段代码无法编译,我会说这是一个错误或者至少很奇怪..

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;
    }
}

即使这样也行不通

public class QualifierConfiguration {
    public static final String RANK_CALCULATOR = getValue();
    private static String getValue(){
        return "string";
    }
}

【问题讨论】:

  • 你有没有进一步追求这个?

标签: java


【解决方案1】:

final 变量不一定是编译时常量:

4.12.4. final Variables

变量可以声明为final。最终变量只能分配一次。

常量变量是原始类型或String 类型的最终变量,它使用常量表达式 (§15.28) 进行初始化。

RankCalculatorImpl.class.getName() 不是常量表达式,getValue() 也不是。

请注意,对于具有 Class 值的注释,由于注释的特定规则,允许使用像 RankCalculatorImpl.class 这样的类文字,但它们仍然不会生成编译时常量(同样适用于 enum不断引用)。对于原始值和String 值,the specification 明确要求注释值的常量表达式:

当且仅当满足以下条件之一时,元素类型 T 与元素值 V 相称:

  • T 不是数组类型,V 的类型与 T 的赋值兼容(第 5.2 节),并且:

    • 如果T 是原始类型或String,则V 是常量表达式(第15.28 节)。
    • 如果TClassClass 的调用(第4.5 节),那么V 是一个类文字(第15.8.2 节)。
    • 如果 T 是枚举类型(第 8.9 节),则 V 是枚举常量(第 8.9.1 节)。
    • V 不是 null

所以在这里,您别无选择,只能将实际的限定名称指定为字符串文字:

public static final String RANK_CALCULATOR = "actual.package.name.RankCalculatorImpl";

【讨论】:

    【解决方案2】:

    您必须将常量表达式传递给注释。所以它必须在编译期间保持不变。您可以获取有关编译时常量here 的更多信息。类似的 SO 问题here

    你从中得到的例外是:The value for annotation attribute Qualifier.value must be a constant expression

    【讨论】:

      猜你喜欢
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-07
      • 2020-04-23
      • 1970-01-01
      • 2018-08-23
      相关资源
      最近更新 更多