1、引子java
在各类教科书和博客中这三者常常被引用,今天复习到内存区域,想起常量池中就是存着字面量和符号引用,其实这三者并非只在java中才有,各个语言中都有相似的定义,因此作一下总结,以示区分。数组
2、例子缓存
先举一个简单的例子,就很容易看懂接下来的定义了。性能
int a; //变量 final int b = 10; //b为常量,10为字面量 string str = “hello world!”; // str 为变量,hello world!为字面量
3、各定义以及区分spa
3.1 变量code
有些数据在程序运行中能够变化或者被赋值,这称为变量。例如:对象
int a; String b;
3.2 常量blog
java中是指以final关键字修饰的变量(C语言中是constant关键字),在初始化的时候必须被赋值,而且此值和类型不能再发生改变。例如:内存
final int a; final String b;
3.3 字面量字符串
在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(natation)。
是否是仍是看不懂?我通常采用一个特殊的区分方法:等号右边的八种基本类型的值、字符串值、声明为final的常量的值。例如:
final int a = 10; //a为常量,10为字面量 string b = “hello world!”; // b 为变量,hello world!为字面量
4、Integer的缓存机制
注意,有个容易误解的地方:关于Integer在-128到127之间的缓存问题。
这个问题不少人其实都知道——若是值在-128到127之间,Integer对象的引用地址是相等的。身边不少朋友都说是字面量在常量池中缓存的缘由。
其实并非的,这是Integer的缓存机制:
在Integer类中,定义了一个私有的静态类IntegerCache,这个类是用来支持Integer缓存的,它的做用是把一部分Integer类型的对象在Integer类加载的时候一块儿建立出来并放在一个cache数组中,以便之后循环使用。一般这个范围是-128-127,然而这个范围的最大值是可变的,能够经过-XX:AutoBoxCacheMax=<size>参数去修改这个值,在JVM初始化的时候,这个值被写入sun.misc.VM class系统私有配置文件中,并加载。(由于会一次性所有建立出来,因此这个数值会影响到启动性能)
【Byte,Short,Long 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127。除了 Integer 能够经过参数改变范围外,其它的都不行。】
... cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); ...
而后在调用valueOf(int i)方法的时候(自动封装就是调用这个方法),就会判断 i 是否在这个范围以内,是的话就会返回这个静态类维护的cache数组里对应的对象。因此说在这个范围内值相同的对象的引用是相同的。
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
示例:
Integer integer1 = new Integer(121); Integer integer2 = 121; // 编译器编译成调用valueOf(int i) Integer integer3 = Integer.valueOf(121); System.out.println(integer1 == integer2); // false System.out.println(integer2 == integer3); // true
可见new出来的对象并不会从Integer缓存中去取。