常量设计(1):
常量:一种不会修改的变量
--Java没有constant关键字
--不能修改,final
--不会修改 / 只读 / 只要一份,static
--方便访问public
Java中的常量:
--public static final
--建议变量名字全部大写,以连字符相连,比如UPPER_BOUND
常量设计(2):
如果变量是static且final的,static保证只有一份,final保证值不会被修改,那么这个变量就是常量。
常量设计(3):
一种特殊的常量:接口中定义的变量默认都是常量
--实现接口,就需要遵循接口的定义,就是尊重契约精神。所以接口的变量就是以常量的形式存在。
--如果将上述代码中接口中的String color改为private String color,编译都通不过
常量池(2):
--Java为了提高程序性能,为很多基本类型的包装类 / 字符串都建立常量池
--常量池:相同的值只存储一份,节省内存,共享访问(简单地说,确定的值,就用一个东西把他框起来,那么需要用的话,大家都指向这个地方)
--所以常量池为哪些包装类提供这个“服务”?首先明白什么是包装类,包装类就是8个基本类型的(包装类),因为Java操作的东西大部分都是对象,把每一个基本型别/类型都定义了一个相应的类对象,比如从一个小的int,变成了一个大的Integer。
--基本类型的包装类:
提供常量池的包装类:Boolean, Byte, Short, Integer, Long, Character,没有提供常量池的包装类:Float, Double
其中提供了常量池也是有个范围的:
Boolean: true, false
Byte: -128 ~ 127
Character: 0 ~ 127
Short, Integer, Long: -128 ~ 127
Float, Double:没有缓存(常量池)
--查看CacheTest.java
常量池(3):
--Java为常量字符串都建立常量池缓存机制
--字符串常量:
常量池起到的作用:
(1)节约内存
(2)共享访问
常量池(4):
基本类型的包装类和字符串有两种创建方式:
(1)常量式(字面量)赋值创建,放在栈内存(将被常量化)
Integer a = 10;
String b = "abc" ;
(2)new对象进行创建,放在堆内存(不会被常量化)
Integer c = new Integer(10) ;
String d = new String ( "abc" ) ;
这两种创建方式导致创建的对象存放的位置不同。
为什么通过new对象的方式进行创建包装类的变量,要放在堆内存呢?因为new将根据构造函数来创建对象。Java觉得这种对象会比较庞大,有可能中间的值比较大,所以会把它放在大一点的内存上,如堆内存。
举个例子,看看Integer(基本类型的包装类)和String字符串类是怎么用的?
自动装箱的意思是说,Integer i2 = 10; 10只是一个int基本型别的变量,我们希望把它变成一个对象,相当于把10做了一层包装。
包装类对象(两种方式都是)的加法会自动拆箱。
常量池(5):
--查看BoxClassTest.java分析Integer类
基本类型和包装类对象比较,将对包装类自动拆箱
包装类对象之间比较,比较地址(对象存在栈内存还是堆内存)
加法,包装类会自动拆箱
--查看StringNewTest.java分析String类
常量赋值(栈内存)和new创建(堆内存)不是同一个对象
编译器只会优化确定的字符串,并且缓存
总结:
--Java中的常量: static和final
--Java接口中的变量都是常量
--对象生成有两种:常量赋值(栈内存)和new创建(堆内存)
--Java为Boolean,Byte,Character,Short,Int,Long,String的常量赋值建立常量池,没有包括Float和Double
--Java编译器会优化已经确定的变量