第六章 static, final和常量设计(续)
第四节 常量设计和常量池
常量:一种不会修改的变量
- Java没有constant关键字
- 不能修改,final
- 不会修改/只读,static
- 方便访问public
Java中的常量
- public static final
- 建议变量名字全大写,以连字符相连,如UPPER_BOUND
Java为很多基本类型的包装类/字符串都建立常量池。
常量池:相同的值只存储一份,节省内存,共享访问。
基本类型的包装类:
- Boolean, Byte, Short, Integer, Long, Character
- Boolean: true, false
- Byte: -128 ~ 127, Character: 0 ~ 127
- Short, Int, Long: -128 ~ 127
- Float, Double: 没有缓存(常量池)
Java为常量字符串都建立常量池缓存机制。
基本类型的包装类和字符串有两种创建方式:
- 常量式赋值创建,放在栈内存(将被常量化),读取速度快但容量小。
· Integer a = 10;
· String b = "abc";
- new对象进行创建,放在堆内存(不会常量化),读取速度慢但容量大。
· Integer c = new Integer(10);
· String b = new String("abc");
i4和i5是两个(包装类Integer)的对象。i4+i5将会自动拆箱,变换为两个int的加法,即5+5,所以i4+i5的结果为10,是int类型,不是Integer的对象。
第五节 不可变对象和字符串
常量是不会被修改的,在内存空间中,只需要保留一份,只读。
不可变对象(Immutable Object)
- 一旦创建,这个对象(状态/值)不能被更改了
- 其内在的成员变量的值就不能修改了
- 八个基本型别的包装类
- String, BigInteger和BigDecimal等
可变对象(Mutable Object)
- 普通对象
如何创建不可变对象:
- immutable对象是不可改变的,有改变,请clone/new一个对象进行修改
- 所有等属性都是final和private的
- 不提供setter方法
- 类是final的,或者所有的方法都是final
- 类中包含mutable对象,那么返回拷贝需要深度clone
不可变对象的优点:
- 只读,线程安全
- 并发读,提高性能
- 可以重复使用
- 缺点:制造垃圾,浪费空间
字符串是Java使用最多的类,是一种典型的不可变对象。
String的定义有两周:
- String a = "abc"; //常量复制,栈分配内存
- String b = new String("abc"); //new对象,堆分配内存
字符换内容比较:equals方法
是否指向同一个对象:指针比较==
String a = "abc"; a = a + "def"; // 由于String不可修改,效率差。本质上是创建了一个新的abcdef让a指向它,原本的abc还存在,只是没有指针指向。
使用StringBuffer/StringBuilder的对象都是可变对象。
StringBuffer同步,线程安全,修改快速。
StringBuilder不同步,线程不安全,修改更快。
使用StringBuffer