Java编译时常量和运行时常量
Java编译时常量和运行时常量
编译期常量指的就是程序在编译时就能确定这个常量的具体值。
非编译期常量就是程序在运行时才能确定常量的值,因此也称为运行时常量。
在Java中,编译期常量指的是用final关键字修饰的基本类型或String类型并直接赋值(非复杂运算)的变量(无论是否用static修饰),是编译器的一种优化,体现在字节码文件中;运行是常量是由运行时解释器解释完成的。
运行时常量很容易理解,接下来会简单的结合字节码文件来介绍编译时常量及使用风险。
public class ConstantTest {
public final int a = 1; //编译时常量
public final int b = 1+2; //编译时常量 支持加减乘除等简单运算
public final int c = b+3; //编译时常量
public final static int d = 10; //编译时常量
public final String str1 = "abc"; //编译时常量
public final String str2 = "def" + "ghi"; //编译时常量 支持字符串的连接
public final String str3 = str2 + "jkl"; //编译时常量
public final static String str4 = "static str"; //编译时常量
public final double e = Math.random(); //运行时常量
public final ConstantTest test = new ConstantTest(); //运行时常量
}
下面是编译后相应的字节码信息:

注意!!!!!!
类B中所有引用类A中用static final修饰的静态编译时常量都会在编译时全部替换为相应的数值或字符串,所以当修改了类A中的静态编译时常量时,类A和类B都要重新编译,如果只重新编译类A,则类B还是会引用之前的常量。
以下是案例:
类ConstantTest:
public class ConstantTest {
public final int a = 1;
public final int b = 1+2;
public final int c = b+3;
public final static int d = 10;
public final String str1 = "abc";
public final String str2 = "def" + "ghi";
public final String str3 = str2 + "jkl";
public final static String str4 = "static str";
public final double e = Math.random();
public final ConstantTest test = new ConstantTest();
}
类Test引用ConstantTest中的静态编译时常量:
public class Test{
public int m = ConstantTest.d;
public static int n = ConstantTest.d;
public final int g = ConstantTest.d;
public static final int j = ConstantTest.d;
public static void main(String[] args) {
int k = ConstantTest.d;
System.out.println("m="+new Test().m);
System.out.println("n="+n);
System.out.println("g="+new Test().g);
System.out.println("j="+j);
System.out.println("k="+k);
}
}
首先全部编译,运行Test类:

修改ConstantTest中静态常量的值为20后只重新编译ConstantTest,运行结果:

重新编译Test后,运行结果:

最后总结一下:
- 编译期常量指的是用final关键字修饰的基本类型或String类型并直接赋值(非复杂运算)的变量(无论是否用static修饰);
- 运行时常量是程序在运行时才能确定值的一种常量;
- 所有引用其他类中静态编译时常量(一般就叫静态常量,用static final修饰)的类在字节码中全部替换为相应常量的值,所以引用静态常量并不会触发该类的的初始化。
Java编译时常量和运行时常量的更多相关文章
- Java编译时多态和运行时多态
来源:https://blog.csdn.net/wendizhou/article/details/73733061 编译时多态:主要是方法的重载,通过参数列表的不同来区分不同的方法. 运行时多态: ...
- 正确理解java编译时,运行时以及构建时这三个概念
Java中的许多对象(一般都是具有父子类关系的父类对象)在运行时都会出现两种类型:编译时类型和运行时类型,例如:Person person = new Student();这行代码将会生成一个pers ...
- [转] Java 的泛型擦除和运行时泛型信息获取
原文链接 https://my.oschina.net/lifany/blog/875769 前言 现在很多程序员都会在简历中写上精通 Java.但究竟怎样才算是精通 Java 呢?我觉得不仅要熟练掌 ...
- 将子类对象引用赋值给超类对象 JAVA 编译时多态性
将子类对象引用赋值给超类对象 JAVA 编译时多态性(转) (2012-05-10 11:24:05) 转载▼ 标签: 杂谈 分类: 也无晴_soft 1.通过将子类对象引用赋值给超类对象引用变量来实 ...
- in C#,编译型常量(const)和运行时常量(readonly)
readonly 关键字与 const 关键字不同. const 字段只能在该字段的声明中初始化. readonly 字段可以在声明或构造函数中初始化. 因此,根据所使用的构造函数, readonly ...
- 关于JAVA编译时找不到自定义包的问题
这两天照网上的教程,学习JSP/SERVLET/JAVABEAN,写了几个JAVA文件,目录放在TOMCAT的WEBAPPS下面,通过javac编译时,老提示找不到指定的包: 下图是我的目录路径: 通 ...
- java 编译时注解框架 lombok-ex
lombok-ex lombok-ex 是一款类似于 lombok 的编译时注解框架. 编译时注,拥有运行时注解的便利性,和无任何损失的性能. 主要补充一些 lombok 没有实现,且自己会用到的常见 ...
- Java编译时根据调用该方法的类或对象所属的类决定
class Base{ int x = 1; static int y = 2; } class Subclass extends Base{ int x = 4; i ...
- Java方法区和运行时常量池溢出问题分析
运行时常量池是方法区的一部分,方法区用于存放Class的相关信息,如类名.访问修饰符.常量池.字段描述.方法描述等. String.intern()是一个native方法,它的作用是:如果字符串常量池 ...
随机推荐
- 【数据结构】之链表(Java语言描述)
以前写过一篇帖子,记录了链表在C语言中的描述代码.C语言中没有链表的直接实现,因此,我们需要自己编写代码实现.请参考[我的这篇文章]. Java中默认为我们提供了链表的API—— LinkedList ...
- windows下python IDE安装注意事项&Python安装及编辑器UliPad安装
python下载地址: http://www.python.org/download/releases/2.7.6/ 我自己用的是ulipad ,但是注意 ulipad和python的版本一定要配 ...
- Feign超时设置
转-原文:https://xli1224.github.io/2017/09/22/configure-feign/ 在分析 Feign 源码的时候,我们看到 Feign 构建代理对象是分了几层的,一 ...
- Netty学习——Apache Thrift 简介和下载安装
Netty学习——Apache Thrift 简介和下载安装 Apache Thrift 简介 本来由Facebook开发,捐献给了Apache,成了Apache的一个重要项目 可伸缩的,跨语言的服务 ...
- Python装饰器总结,带你几步跨越此坑!
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...
- Spring MVC上传文件原理和resolveLazily说明
问题:使用Spring MVC上传大文件,发现从页面提交,到进入后台controller,时间很长.怀疑是文件上传完成后,才进入.由于在HTTP首部自定义了“Token”字段用于权限校验,Token的 ...
- sublime text3安装中文版插件
安装插件前需要先安装 package control 扩展包管理器,安装方法为:进入 https://sublime.wbond.net/Package%20Control.sublime-packa ...
- Java修炼——线程同步的俩种方法
当多线程去同时抢占CPU资源时,有多线程的安全问题.这时候就需要将线程同步.线程同步有俩个方法. 1.同步代码块(synchronize),同步代码块需要同步监视器,同步监视器是针对对象进行操作.什么 ...
- CSS_跳动的心
详细教程CSS3 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...
- Zabbix通过与微信、钉钉整合实现实时告警
abbix可以通过多种方式把告警信息发送到指定人,常用的有邮件,短信报警方式,但是越来越多的企业开始使用zabbix结合微信.钉钉作为主要的告警方式,这样可以及时有效的把告警信息推送到接收人,方便告警 ...