美文网首页
Java Compile-time Constant 编译时常量

Java Compile-time Constant 编译时常量

作者: yougang | 来源:发表于2016-01-01 12:36 被阅读1334次

问题描述

如何将非字符串常量转为字符串常量?toStringString.valueOf 貌似都无法编译。

在给注解属性赋值的时候:

private final static String MAX_VALUE_AS_STRING = Long.toString(Long.MAX_VALUE);
...
@Annotation(value = MAX_VALUE_AS_STRING)

编译器一直报错:

attribute must be constant 值类型必须是常量

MAX_VALUE_AS_STRING 不是明明就是个常量,而且是运行时常量啊。而且在官方的文档中,明明就有 Integer.MAX_VALUE / 2的说明。

为了搞清楚这一点,还是要从官方文档入手,细细分析什么是常量。

## Java编译时常量解释

首先,编译器告诉了你这个属性必须是个常量值,但是并没有告诉你,这个属性其实必须是一个编译时常量值。所谓编译时常量就是在编译阶段已经可以确定其值的常量。

Oracle的官方文档 15.28 Constant Expressions 也详细的解释了,什么是 ** Compile-time Constant **

1. 原始类型字面量,或者String字面量
2. 能转型为原始类型字面量,或String字面量的常量
3. 一元运算符(+,-,~,!,但不包含++, --) 和1,2组成的表达式 
4. 多元运算符(*,/和%)和1,2组成的表达式
5. 附加运算符( additive operators) (+ 或 -)与之前几条组成的表达式
6. 位移运算符(<<,>>, >>>)和之前几条组成的表达式
7. 关系运算符(<,<=,>,>= ,不包括 instanceof)与之前几条组成的表达式
8. 关系运算符(==,!=)与之前几条组成的表达式
9. 位运算符(&, ^, |)与之前几条组成的表达式
10. 条件与和条件或运算符(&&, ||) 与之前几条组成的表达式
11. 三元运算符 (?:)和之前几条组成的表达式
12. 带括号的表达式,括号内也是常量表达式
13. 引用常量变量的简单变量 [§6.5.6.1](https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.5.6.1)
14. 类中的常量变量引用,使用类的全限定名或类名进行引用(String.class)

由上述14条规则组成的常量成为编译时常量。

所以针对上一个问题,任何的方法调用其实都不在描述范围当中。因此不管是使用 Long.toString(Long.MAX_VALUE) 还是使用 String.valueOf(Long.MAX_VALUE),在编译时都是非法的。

解决方案

既然不能使用方法调用,进行类型转换,如何实现将 Long.MAX_VALUE 转换为常量字符串呢?
其实很简单:

public static final String MAX_VALUE_AS_STRING = Long.MAX_VALUE + "";

这个方式就符合原始类型字面量和String字面量的二元运算这条规则。

终于搞明白了:)

相关文章

  • Java Compile-time Constant 编译时常量

    问题描述 如何将非字符串常量转为字符串常量?toString和 String.valueOf 貌似都无法编译。 在...

  • 面试系列(2)Java String

    1、常量池 Java 被编译成 class 文件时,会生成一个常量池(Constant pool)的数据结构,用于...

  • solidity-3.常量

    常量(constant state variables) 状态变量可以被定义为constant常量,类似于java...

  • JVM扩展(3):常量池引发的一连串思考(下)

    目录 1:源码的编译(包括类加载过程) 2:静态常量池(类常量池)(类文件常量池)(class constant ...

  • Java-常量池

    相关概念 常量池的定义常量池(constant pool):指的是在编译期被确定,并被保存在已编译的.class文...

  • 类常量池和运行时常量池的区别

    首先常量池分为类编译后的常量池和运行时常量池类的常量池为类编译后生成的 Constant pool:在代码运行时会...

  • JVM(六)JVM常量池

    1.常量池类型 Java中的常量池分为三种: 类文件常量池(静态常量池)(The Constant Pool)运行...

  • 零基础Java学习必备单词

    Java类的单词 语法 :grammar 变量 : varianle 常量 :constant 初始化 : ini...

  • 常量

    常量  Java中由final修饰的就是常量。如下:  分类:编译期常量和运行时常量 编译期常量:它的值在编译期就...

  • 错题集

    引用final static 的常量编译后存储常量而不是引用 编译后: 如果修改 One.java 后编译One....

网友评论

      本文标题:Java Compile-time Constant 编译时常量

      本文链接:https://www.haomeiwen.com/subject/syxwhttx.html