码迷,mamicode.com
首页 > 编程语言 > 详细

java的不可变类

时间:2015-06-08 16:49:55      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

 1、Integer

public static void main(String[]args) {
       Integer i=new Integer(1);
       System.out.println(i.intValue());        
       i=2;
       System.out.println(i.intValue());
}

我们知道Integer的属性value的类型为:final int value;

而方法intValue就是返回value。

很显然,上面两次打印结果是不同的,而都是同一个引用变量i。然道我们对置为1的Integer实例做了修改,将其value值变成了2?

很显然,这种结论是不正确的,因为它违反了final修饰变量的特性。

1 public class Test {
2     public static void main(String[]args) {
3         Integer i=new Integer(1);    
4         System.out.println(System.identityHashCode(i));
5         i=2;
6         System.out.println(System.identityHashCode(i));
7     }
8 }

通过这段代码,可知,value值为1的实例和value值为2的实例是两个不同的实例。正如上说,因为value属性是由final修饰的,因此这个类是不可变的。

内存空间释义图如下:

技术分享

 由释义图可知,改变了value值,其实就是新生成了一个空间,改变引用变量的指示方向;而原先那个value值为1的实例就变成了游离的实例,成为java虚拟机回收的对象目标。正因为,要想改变value就得重启一个空间,这是比较消耗性能的,因此Integer会对[-128,127]范围类的值的实例缓存下来。

 

 

2、String

其属性类型为final char value[];

因此String类也是不可变的。

 

和Integer一样,改变value值就得新开辟一个空间,这也是性能上的一种消耗,因此,Java给String的字面量也提供了缓存,如果某个字符串的字面量能够

在缓存池当中找到那么就会复用(编译阶段完成的)。

 1     public static void main(String[]args) {
 2         String str1="feijishuo";
 3         String str2="feijishuo";
 4         System.out.println(str1==str2); //true
 5         
 6         String str3="feiji";
 7         String str4="fei";
 8         String str5="ji";
 9         String str6="fei"+"ji";
10         String str7=str4+str5;
11         System.out.println(str3==str6); //true
12         System.out.println(str3==str7); //false
13
14 final String Str8="fei";
15 String str9=str8+"ji";
16 System.out.println(str3==str9); //true
17
}

代码分析:str1和str2指向同一个实例,那是因为字面相同,它们会存在于缓存池(编译时常量池)当中。

              str3和str6指向同一个实例,因为字面量“fei”和“ji”在编译时就确定下来了,那么str6在编译时候也能确定下来,然后这个字面量已经在

     缓存池(编译时常量池)当中存在了,因此就不用生成新的实例了,只要将引用变量指向存在的实例即可。

              str3和str7不是同一个实例,因为变量只有在运行期间才能知道其所指示的值。

              str3和str9是同一个实例,因为变量str8定义为final类型的,因此其在编译期间就能确定下来。其实例已经存在常量池(编译时常量池)当中

      存在,因此不会生成新的实例。于是,构成str9的式子都能在编译期间在常量池中找到,因此str9在编译期间也就确定了下来,其实例在常量池中已经存       在。

 

java的不可变类

标签:

原文地址:http://www.cnblogs.com/feijishuo/p/4560963.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!