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

在Java中String类为什么要设计成final?String真的不可变吗?其他基本类型的包装类也是不可变的吗?

时间:2018-07-26 10:48:45      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:javap   一个   通过   定义   性能   枚举类   代码   tde   常量池   

最近突然被问到String为什么被设计为不可变,当时有点懵,这个问题一直像bug一样存在,竟然没有发现,没有思考到,在此总结一下。

1.String的不可变
String类被final修饰,是不可继承和修改的。当一个String变量被第二次赋值时,不是在原有内存地址上修改数据,而是在内存中重新开辟一块内存地址,并指向新地址。

技术分享图片

String类为什么要被设计为是final的?

  1.不可变性支持线程安全
  2.不可变性支持字符串常量池,提升性能
  3.String字符串作为最常用数据类型之一,不可变防止了随意修改,保证了数据的安全性

正常情况下Java的String字符串是final且不可变的。不过可以通过特殊手段修改它的内容。
String类的主力成员字段value是个char[ ]数组,而且是用final修饰的。final修饰的字段创建以后就不可改变。因为虽然value是不可变,也只是value这个引用地址不可变。挡不住Array数组是可变的事实。Array的数据结构看下图:

技术分享图片

也就是说Array变量只是stack上的一个引用,数组的本体结构在heap堆。String类里的value用final修饰,只是说stack里的这个叫value的引用地址不可变。没有说堆里array本身数据不可变。

代码测试:

 1 String test = "immutable String";
 2 String test1 = test;
 3 String test2 = new String(test);
 4 String test3 = new String(test.toCharArray());
 5 Field values = String.class.getDeclaredField("value");
 6 values.setAccessible(true);
 7 char[] chars = (char[])values.get(test);
 8 chars[0] = u;
 9 chars[1] = n;
10 System.out.println("test==test1:" + (test == test1));
11 System.out.println("test==test2:" + (test == test2));
12 System.out.println("test1==test2:" + (test1 == test2));
13 System.out.println("test:" + test + "   test1:" + test1 + " test2:" + test2 + "  test3:" + test3);

技术分享图片

由String的不可变性引申到其他基本数据类型: Byte,Short,Integer,Long,Double,Float,Character,Boolean 八种基本数据的包装类,仔细查看发现也是final修饰的,再仔细查看一下enum枚举类型,发现用javac编译后再用javap反编译也是被编译为final修饰的类,并且其枚举值全部定义为static final 修饰的成员变量。

技术分享图片

由此发现,Java设计者在设计Java基本数据类型时,把基本数据类型全部设计为不可变的,这样既方便了开发人员,又保证了数据的安全性。

总结:Java中String是不可变的,但是可以通过反射修改其内容

备注:
作者:Shengming Zeng
博客:http://www.cnblogs.com/zengming/ 

本文是原创,欢迎大家转载;但转载时必须注明文章来源,且在文章开头明显处给明链接。
<欢迎有不同想法或见解的同学一起探讨,共同进步>

在Java中String类为什么要设计成final?String真的不可变吗?其他基本类型的包装类也是不可变的吗?

标签:javap   一个   通过   定义   性能   枚举类   代码   tde   常量池   

原文地址:https://www.cnblogs.com/zengming/p/9367088.html

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