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后,运行结果:

  最后总结一下:

  1. 编译期常量指的是用final关键字修饰的基本类型或String类型并直接赋值(非复杂运算)的变量(无论是否用static修饰);
  2. 运行时常量是程序在运行时才能确定值的一种常量;
  3. 所有引用其他类中静态编译时常量(一般就叫静态常量,用static final修饰)的类在字节码中全部替换为相应常量的值,所以引用静态常量并不会触发该类的的初始化。

Java编译时常量和运行时常量的更多相关文章

  1. Java编译时多态和运行时多态

    来源:https://blog.csdn.net/wendizhou/article/details/73733061 编译时多态:主要是方法的重载,通过参数列表的不同来区分不同的方法. 运行时多态: ...

  2. 正确理解java编译时,运行时以及构建时这三个概念

    Java中的许多对象(一般都是具有父子类关系的父类对象)在运行时都会出现两种类型:编译时类型和运行时类型,例如:Person person = new Student();这行代码将会生成一个pers ...

  3. [转] Java 的泛型擦除和运行时泛型信息获取

    原文链接 https://my.oschina.net/lifany/blog/875769 前言 现在很多程序员都会在简历中写上精通 Java.但究竟怎样才算是精通 Java 呢?我觉得不仅要熟练掌 ...

  4. 将子类对象引用赋值给超类对象 JAVA 编译时多态性

    将子类对象引用赋值给超类对象 JAVA 编译时多态性(转) (2012-05-10 11:24:05) 转载▼ 标签: 杂谈 分类: 也无晴_soft 1.通过将子类对象引用赋值给超类对象引用变量来实 ...

  5. in C#,编译型常量(const)和运行时常量(readonly)

    readonly 关键字与 const 关键字不同. const 字段只能在该字段的声明中初始化. readonly 字段可以在声明或构造函数中初始化. 因此,根据所使用的构造函数, readonly ...

  6. 关于JAVA编译时找不到自定义包的问题

    这两天照网上的教程,学习JSP/SERVLET/JAVABEAN,写了几个JAVA文件,目录放在TOMCAT的WEBAPPS下面,通过javac编译时,老提示找不到指定的包: 下图是我的目录路径: 通 ...

  7. java 编译时注解框架 lombok-ex

    lombok-ex lombok-ex 是一款类似于 lombok 的编译时注解框架. 编译时注,拥有运行时注解的便利性,和无任何损失的性能. 主要补充一些 lombok 没有实现,且自己会用到的常见 ...

  8. Java编译时根据调用该方法的类或对象所属的类决定

    class Base{     int x = 1;     static int y = 2; } class Subclass extends Base{     int x = 4;     i ...

  9. Java方法区和运行时常量池溢出问题分析

    运行时常量池是方法区的一部分,方法区用于存放Class的相关信息,如类名.访问修饰符.常量池.字段描述.方法描述等. String.intern()是一个native方法,它的作用是:如果字符串常量池 ...

随机推荐

  1. 用 python 分析基金!让赚钱赢在起跑线!

    你不理财,财不理你!python 也能帮你理财? 效果预览 累计收益率走势图 基本信息结果 如何使用: python3 + 一些第三方库 import requests import pandas i ...

  2. supersocket/SocketEngin/BootstrapFactory.cs 详解

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using SuperSoc ...

  3. Django ORM-objects-QuerySet

    Django ORM ORM执行查看原生SQL的两种方法 1.在setting中配置 LOGGING = { 'version': 1, 'disable_existing_loggers': Fal ...

  4. Zip压缩工具、tar打包、打包并压缩

    第5周第2次课(4月17日) 课程内容: 6.5 zip压缩工具6.6 tar打包6.7 打包并压缩 6.5 zip压缩工具 Zip压缩工具最大的特点就是可以支持压缩目录,也能够压缩文件,Window ...

  5. 【游记】CSP J/S 2019 游记

    J 组 \(2:30\)开始, \(2:13\)还在酒店的我看了看手表...飞奔考场. T1 数字游戏 秒切. 下午某中学某大佬说可用线性基(%) T2 公交换乘 用单调队列思想,秒切. T3 纪念品 ...

  6. 【原创】002 | 搭上SpringBoot事务源码分析专车

    前言 如果这是你第二次看到师长,说明你在觊觎我的美色! 点赞+关注再看,养成习惯 没别的意思,就是需要你的窥屏^_^ 专车介绍** 该趟专车是开往Spring Boot事务源码分析的专车 专车问题 为 ...

  7. java基础-泛型举例详解

    泛型 泛型是JDK5.0增加的新特性,泛型的本质是参数化类型,即所操作的数据类型被指定为一个参数.这种类型参数可以在类.接口.和方法的创建中,分别被称为泛型类.泛型接口.泛型方法. 一.认识泛型 在没 ...

  8. Gradle+Groovy提高篇

    创建自定义任务 打开build.gradle文件,并在末尾添加以下内容: println "1" task howdy { println "2" doLast ...

  9. h5-面试题

    干货!各种常见布局实现+知名网站实例分析 前端面试考点多?看这些文章就够了(2019年6月更新版) 前端面试:这50个经典前端面试题面试者必看! Vue面试中,经常会被问到的面试题/Vue知识点整理 ...

  10. JSP请求是如何被处理的?jsp的执行原理

    客户端通过浏览器发送jsp请求,服务器端接受到请求后,判断是否是第一次请求该页面,或者该页面是否改变,若是,服务器将jsp页面翻译为servlet,jvm将servlet编译为.class文件,字节码 ...