编译器常量的特点就是:它的值在编译期就可以确定。比如:

  final int i = 5;

  再傻的编译器也能在编译时看出它的值是5,不需要到运行时。对于运行时常量,它的值虽然在运行时初始化后不再发生变化,但问题就在于它的初始值要到运行时才能确定。

  比如:

  Random rand = new Random(47);

  final int i4 = rand.nextInt(20);

  虽然i4的值在定义并初始化后不会再发生变化(除非你使用一些不符合标准的小技巧),但再聪明的编译器也无法在编译时确定它的值呀。

  为了更清楚的理解编译器常量的概念,我们引入【常量折叠】的概念:在编译器里进行语法分析的时候,将常量表达式计算求值,并用求得的值来替换表达式,放入常量表,可以算作一种编译优化。

  对于编译期常量,编译器常常在编译时就可以折叠开。而对于运行期常量,编译期无法折叠,编译器能做的,只是对所有可能修改它的动作报错。

案例1:

package testPage;

class InitalizedClass {
static {
System.out.println("You have initalized InitalizedClass!");
}
public static int inititalize_varible = 1; } public class TestInitializeClass { public static void main(String[] args) {
System.out.println(InitalizedClass.inititalize_varible);
}
/**
* 输出结果为:
* You have initalized InitalizedClass!
* 1
*/ }

案例2:

package testPage;

class InitalizedClass {
static {
System.out.println("You have initalized InitalizedClass!");
}
//和上面的例子唯一的差异就是此处的变量INITIALIZED_VARIBLE被声明为final
public final static int INITIALIZED_VARIBLE = 1; } public class TestInitializeClass {
public static void main(String[] args) {
System.out.println(InitalizedClass.INITIALIZED_VARIBLE);
}
/**
* 输出结果为:
* 1
*/
}

  为什么两个例子执行结果不一样,原因是第二个例子中的INITIALIZED_VARIBLE为编译期常量,它不会导致类的初始化。

参考资料:

http://bbs.csdn.net/topics/100054572

http://chihom.iteye.com/blog/233035

JAVA编译器常量的更多相关文章

  1. ☕【Java技术指南】「编译器专题」重塑认识Java编译器的执行过程(常量优化机制)!

    问题概括 静态常量可以再编译器确定字面量,但常量并不一定在编译期就确定了, 也可以在运行时确定,所以Java针对某些情况制定了常量优化机制. 常量优化机制 给一个变量赋值,如果等于号的右边是常量的表达 ...

  2. Java编译器、JVM、解释器

    Java虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该系统上运行.本文首先简要介绍从Java文件的编译 ...

  3. java编译器优化和运行期优化

    概述    最近在看jvm优化,总结一下学习的相关知识 (一)javac编译器 编译过程 1.解析与填充符号表过程 1).词法.语法分析    词法分析将源代码的字符流转变为标记集合,单个字符是程序编 ...

  4. Java字符串常量池及字符串判等解析

    一.理解"=="的含义 "=="常用于两个对象的判等操作,在Java中,"=="主要有以下两种用法: 1.基础数据类型:比较的是他们的值是否 ...

  5. 打印class文件的Java编译器内部的版本号

    当改变了jdk版本时,在编译java时,会遇到Unsupported major.minor version错误.错误信息如下 : Unsupported major.minor version 50 ...

  6. 警惕Java编译器中那些“蜜糖”陷阱

    一.前言 随着Java编译器不断地向前发展,它为程序员们提供了越来越多的“蜜糖”(compiler suger),极大地方便了程序的开发,例如,foreach的增强模式,自动拆箱与装箱以及字符串的连接 ...

  7. -1-1 java 基础语法 java关键字 java 注释 常量 语句 运算符 函数 数组定义

    Java语言基础组成 关键字 标识符 注释 常量和变量 运算符 语句 函数 数组 关键字 定义:被Java语言赋予了特殊含义的单词 特点:关键字中所有字母都为小写 用于定义数据类型的关键字 class ...

  8. java中常量文件的配置与读取

    java中常量文件的配置与读取: package com.floor.shop.user.util; import java.io.InputStream; import java.io.InputS ...

  9. (ecj)Eclipse的Java编译器分析之一——ecj介绍

    Java是一个开放的平台,对于除发布编译器/解释器/基础类库之外,该语言的负责机构更多的是制定一系列标准,任何符合标准的厂商产品均可用于市场投放.甚至包括其编译器及解释器. (比如Hibernate提 ...

随机推荐

  1. 【转】如何修改maven工程jdk版本

    1.使用maven的时候,默认会使用1.5版本的JDK,并且也是编译成1.5的,我的电脑里面用的JDK是1.7的,1.8也出来了,没理由还用1.5的吧!所以我手动改成了1.7,郁闷的是,每次 mave ...

  2. Struts2 学习笔记 09 访问Web元素

    我们想要访问Map类型request,session,application.真实类型HttpServletRequest,HttpSession,ServletContext的引用,并对它们进行操作 ...

  3. Java中文件与字节数组转换

    注:来源于JavaEye 文件转化为字节数组: http://www.javaeye.com/topic/304980 /** * 文件转化为字节数组 * * @param file * @retur ...

  4. java类中属性的加载顺序,以及内存分配情况介绍

    看下面例子及说明: /** 假如有外部类调用了该类,代码为:new StaticTest(); 那么下面是类属性的加载顺序 */ public class StaticTest{ public int ...

  5. 给WebAPI的REST接口添加测试页面(三)

    在前面的文章中,我介绍过了通过Swashbuckle在WebAPI中集成Swagger-UI.不过这种方式不适合于最新版的ASP.Net MVC6下的WebAPI,在网上搜了一下,发现了它还有一个专供 ...

  6. 给WebAPI的REST接口服务添加测试页面(一)

    当使用WebAPI提供REST服务的时候,一个经常进行的操作是对接口进行测试.Asp.net WebAPI框架本身并没有提供这一接口,不过由于提供的是标准的REST服务,是可以非常方便的使用一些第三方 ...

  7. AT070TN92 电源

    第二版STM32 + RA8875 + AT070TN92 + 触摸屏 + USB + C++... http://www.amobbs.com/thread-5510972-1-1.html

  8. lua中遍历table的几种方式比较

    当我在工作中使用lua进行开发时,发现在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: for key, value in pairs(tbtes ...

  9. Struts2自定义Result处理JSON

    以前在采用Struts2开发的项目中,对JSON的处理一直都在Action里处理的,在Action中直接Response,最近研读了一下Struts2的源码,发现了一个更加优雅的解决办法,自己定义一个 ...

  10. 《CUDA并行程序设计:GPU编程指南》

    <CUDA并行程序设计:GPU编程指南> 基本信息 原书名:CUDA Programming:A Developer’s Guide to Parallel Computing with ...