为什么Java中的字符串是不可变的?
原文链接:https://www.programcreek.com/2013/04/why-string-is-immutable-in-java/
java字符串是不可变的。不可变类只是一个不能修改实例的类。实例创建时所有的信息都被初始化,并且信息不能被修改。不可变类有许多优点。本文总结了字符串为什么被设计成不可变的原因。这说明在记忆的角度不变性的概念,同步和数据结构。
1.字符串池的要求:
字符串池(字符串特定池)是方法区域中的一个特殊存储区域。当创建字符串时,如果字符串已经存在于池中,则将返回现有字符串的引用,而不是创建新对象。
下面的代码只在堆中创建一个字符串对象:
String string1 = "abcd";
String string2 = "abcd";
如图所示:
如果字符串是可变的,用一个引用更改字符串将导致其他引用的值错误。
2.缓存Hashcode:
在Java中,字符串的Hashcode经常被用到。例如,在一个HashMap或HashSet。一成不变的保证hashcode永远是相同的所以它可以兑现,不用担心变化。这意味着,不需要计算hashCode每次使用它。这更有效。
在String类中,它有以下代码:
private int hash;//this is used to cache hash code.
3.经常使用其他对象:
为了说明这个问题,考虑下面的程序:
HashSet<String> set = new HashSet<String>();
set.add(new String("a"));
set.add(new String("b"));
set.add(new String("c")); for(String a: set)
a.value = "a";
在这个例子中,如果字符串是可变的,它的值是可以改变的,将违反设计集(包含非重复元素)。当然,上面的示例仅用于演示目的,在真正的字符串类中没有值字段。
4.安全:
字符串被广泛用于许多java类的参数,如网络连接、打开文件、字符串等都不是一成不变的,一个连接或文件将被改变,这可能导致严重的安全威胁。方法认为它是连接到一台机器,但不是。可变字符串也可能导致反射中的安全问题,因为参数是字符串。
代码如下:
boolean connect(string s){
if (!isSecure(s)) {
throw new SecurityException();
}
//here will cause problem, if s is changed before this by using other references.
causeProblem(s);
}
5.不可变对象自然是线程安全的:
因为不可变对象不能更改,所以可以在多个线程之间自由共享。这消除了进行同步的要求。
总之,字符串是为了效率和安全原因而不可变的。这也是为什么在很多情况下首选类是不可变类的原因。
为什么Java中的字符串是不可变的?的更多相关文章
- 图说:为什么Java中的字符串被定义为不可变的
8张图,看懂Java字符串的不变性 字符串,想必大家最熟悉不过了,通常我们在代码中有几种方式可以创建字符串,比如:String s = "Hollis";这时,其实会在堆内存中创建 ...
- Java中的字符串常量池
ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...
- 理解Java中的字符串类型
1.Java内置对字符串的支持: 所谓的内置支持,即不用像C语言通过char指针实现字符串类型,并且Java的字符串编码是符合Unicode编码标准,这也意味着不用像C++那样通过使用string和w ...
- java中String类为什么不可变?
在面试中经常遇到这样的问题:1.什么是不可变对象.不可变对象有什么好处.在什么情景下使用它,或者更具体一点,java的String类为什么要设置成不可变类型? 1.不可变对象,顾名思义就是创建后的对象 ...
- 转载:Java中的字符串常量池详细介绍
引用自:http://blog.csdn.net/langhong8/article/details/50938041 这篇文章主要介绍了Java中的字符串常量池详细介绍,JVM为了减少字符串对象的重 ...
- 《Java入门第三季》第二章 认识 Java 中的字符串
什么是 Java 中的字符串.1.在Java的世界里,字符串被作为String类型的对象处理. 2.通用的初始化的方式:String s = new String("i love you & ...
- Java中的字符串常量池和JVM运行时数据区的相关概念
什么是字符串常量池 JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池 工作原理 当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量 ...
- Java中的字符串常量池,栈和堆的概念
问题:String str = new String(“abc”),“abc”在内存中是怎么分配的? 答案是:堆内存.(Tips:jdk1.8 已经将字符串常量池放在堆内存区) 题目考查的为Ja ...
- Java中的字符串操作(比较String,StringBuiler和StringBuffer)
一.前言 刚开始学习Java时,作为只会C语言的小白,就为其中的字符串操作而感到震撼.相比之下,C语言在字节数组中保存一个结尾的\0去表示字符串,想实现字符串拼接,还需要调用strcpy库函数或者自己 ...
随机推荐
- Java 在Word创建表格
表格作为一种可视化交流模式及组织整理数据的手段,在各种场合及文档中应用广泛.常见的表格可包含文字.图片等元素,我们操作表格时可以插入图片.写入文字及格式化表格样式等.下面,将通过Java编程在Word ...
- 【POI】导出xls文件报错:The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook
使用POI导出xls文件,由于数据过多,导致导出xls报错如下: The maximum number of cell styles was exceeded. You can define up t ...
- Hibernate get load的区别
这两个函数都是用来从数据库中加载对象,其区别说起来主要有以下两点: 1.如果数据库中不存在该对象,那么load是抛出一个ObjectNotFound的异常,而get是返回一个空指针 2.加载机制不同 ...
- 2016.7.12 eclispe使用mybatis generator生成代码时提示project E is not exist
运行mybatis-generator之后,出现错误:project E is not exist 错误原因:使用了项目的绝对路径. http://bbs.csdn.net/topics/3914 ...
- 转:java工程师成神之路
转自: http://www.hollischuang.com/archives/489 一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 htt ...
- 安卓获取软硬件信息并上传给server(Socket实现)
首先,项目结构如图--A:分为client部分CheckInfo和server端CheckInfo_Server.CheckInfo获取手机信息(Mac,Cpu,内存,已安装软件信息等)并上传到ser ...
- Android 百度地图开发(二)
这一篇文章主要解说的是百度地图的定位功能,然后还有MyLocationOverlay和PopupOverlay两个地图覆盖物的使用.Overlay是"图层"或"覆盖物&q ...
- remove-duplicates-from-sorted-array-ii——去除重复
Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For exampl ...
- 利用动态图添加Loading动画
opacity:CSS3中的属性,调节透明度,一般取值0.5 添加思想: 1.对超链接添加点击事件,通过new {@onclick="showLoading()"} Html.Ac ...
- AMD和Intel的CPU对比
http://www.lotpc.com/yjzs/5825.html 推荐文章:小白看AMD与intel的cpu架构,AMD慢的原因 CPU核心的发展方向是更低的电压.更低的功耗.更先进的制造工艺. ...