`
SunnyYoona
  • 浏览: 386657 次
社区版块
存档分类
最新评论

[细说Java](2)Java中字符串为什么是不可变的

 
阅读更多
在Java中字符串(String)是一个不可改变的类。一个不可改变的类只是一个对象实例不可修改的简单类。当创建一个对象实例时,对象实例的所有信息都被初始化,并且信息不能被修改。对于不可改变的类来说还有很多优势。上一篇文章很好说明了为什么字符串被设计成不可改变的。只有你很好的掌握了内存,同步,数据结构等知识后,你才能很好的回答这个问题。

1. 字符串常量池的需求

字符串常量区是方法区(Method Area)中一块特殊的存储区域。当一个字符串被创建,如果该字符串已经存在字符串常量区时,相应的返回存在字符串的引用,而不是去新创建一个新的对象返回它的引用。

下面的代码中只会在堆中创建一个字符串对象。
String string1 = "abcd";
String string2 = "abcd";
下面的图能很好的说明:

如果字符串是可以改变的,改动一个字符串的引用将会导致另一个引用出现错误值。

2.缓存HashCode(哈希码)

在Java中一个字符串的哈希码是经常被使用的,例如在hashMap中。不可改变性确保了哈希码总是会保持不变,这样我们就不必担心发生任何变化。换一句话说,我们没有必要每次使用字符串时都要计算哈希码(因为不可改变性确保哈希码保持不变),这是一种更有效率的方式。
在String类中,都会有下列代码:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence{
/** Cache the hash code for the string */
private int hash; // Default to 0
}
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";
在这个例子中,假设String是可变的,那么其值就可以修改,这有违集(set)的设计(集中不包含重复的元素)。这个例子为简单考虑,在真实String类中没有value属性。

4. 安全

String在很多Java类中广泛使用作为参数,例如,网络连接,打开文件等等。如果字符串是可改变的,那么网络连接或者文件都可能会被改变,将导致严重的安全威胁。方法还以为是连接到一台机器上,但实际上却没有。可变字符串可能会导致在反射中出现问题,因为这些参数都是字符串。

boolean connect(string s){
if (!isSecure(s)) {
throw new SecurityException();
}
//如果在这之前s通过其他引用进行改变,这可能会出现问题
causeProblem(s);
}

5. 不可变对象是线程安全的

因为不可变对象是不可改变的,那么它们可以在多个线程之间自由的共享。这就取消了进行同步的需求。

总之,字符串被设计为不可变是为了效率和安全性考虑。这也就是一般情况下优先选择不可变对象的原因。





















分享到:
评论

相关推荐

    细说Java NIO

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代标准I/O(BIO)模型的新选择。NIO在Java 1.4版本引入,它为Java应用提供了高效、低延迟的数据处理方式,特别适合于高...

    细说Java之util类.

    Java中的`util`类是Java开发中不可或缺的一部分,它们提供了许多数据结构和工具类的实现,使得开发者可以方便地处理各种数据。`java.util`包是Java标准库的核心部分,包含了许多用于处理集合、时间日期、随机数生成...

    细说java线程问题

    ### 细说Java线程问题:深入理解与实践 在Java编程中,线程是执行的基本单位,它允许程序在操作系统层面并发执行多个任务。掌握Java线程的原理及其使用方法,对于提升软件性能和响应性至关重要。本文将从线程的概念...

    细说Java之常用集合类

    ### 细说Java之常用集合类 #### 一、引言 在Java开发过程中,我们经常需要处理数据的集合操作,比如存储、检索、排序等。为了方便开发者使用,Java SDK提供了一系列内置的集合类,它们主要位于`java.util`包中。...

    细说Java之常用集合类.rar

    最后,关于学习资源,"细说Java之常用集合类.pdf"这本书籍教程应该详细介绍了这些集合类的用法和实现细节,可以帮助开发者更好地理解和运用Java集合框架。"下载说明.txt"可能包含获取更多资源的指南,如"A5下载- 更...

    《细说PHP(第2版)》

    书中涵盖了变量、常量、数据类型(如字符串、整型、浮点型、布尔型、数组、对象等)、运算符、流程控制(条件语句、循环语句)、函数的使用等基础内容。 3. PHP字符串处理:字符串在Web开发中扮演重要角色,书中...

    《细说php》光盘源码

    2. **字符串与数组操作**:PHP对字符串和数组有丰富的处理函数,源码中会展示如何进行字符串拼接、查找、替换,以及数组的创建、遍历、排序等操作。 3. **文件与目录操作**:学习如何在PHP中读取、写入、创建、删除...

    细说php源码

    2. **字符串与数组操作**:PHP对字符串和数组的支持非常强大,源码中可能包含大量的字符串拼接、查找、替换和数组遍历、排序、合并等操作,这对于理解和优化代码性能至关重要。 3. **文件与目录操作**:在《细说PHP...

    《细说PHP》

    对于网页开发来说,处理表单是不可或缺的部分。《细说PHP》可能会涉及如何使用PHP来接收和处理用户通过HTML表单提交的数据。这通常包括获取表单数据、数据过滤、验证以及如何防止常见的安全问题如SQL注入和跨站脚本...

    韩顺平细说servlet.CreateCode.java

    韩顺平细说servlet.生成验证码的代码

    细说servlet_笔记

    Servlet是Java EE(现在称为Java Platform, Enterprise Edition或 Jakarta EE)技术栈中的核心组件,主要用于构建Web应用程序。本文将深入探讨Servlet的相关知识点,包括它的背景、功能、在Java EE体系中的位置以及...

    《细说PHP》光盘源码

    光盘源码中的文件通常包括了书中各个章节的实例代码,这些代码涵盖了PHP的基本语法、流程控制、函数、数组、字符串操作、文件系统交互、数据库连接(如MySQL)、表单处理、会话管理、错误与异常处理、面向对象编程...

    Better Faster Lighter Java 轻松快速学习java编程

    Java 的开发者正深陷于复杂性的泥沼中而无法自拔。我们正接近一个极限,程序设计师为了撰写程序来支持所选择的结构比解决真正的问题所花的时间更多,但是有必要把 Java 搞的这么困难吗? 不,不是这样的。《轻快的...

    细说php精要版

    数据库操作是PHP应用中不可或缺的一部分。书里会介绍如何使用PHP连接和操作MySQL数据库,包括SQL查询、事务处理、预处理语句等。同时,也会涉及PHP与NoSQL数据库如MongoDB的集成。 错误和异常处理是保证程序健壮性...

    《细说PHP》配套源码

    2. **字符串操作**:PHP对字符串处理提供了丰富的内置函数,如`strlen()`计算长度,`substr()`截取子串,`str_replace()`替换字符串,`strpos()`查找子串位置等,源码中会涵盖这些内容。 3. **数组操作**:PHP的...

    韩顺平细说Servlet源代码

    此外,还会涉及Servlet的多线程模型,讲解为什么Servlet通常是线程安全的,以及如何处理并发访问。 除此之外,课程还会涵盖Servlet的会话管理,包括`HttpSession`对象的使用,以及如何跟踪用户的会话状态。另外,还...

    细说PHP配套源码

    《细说PHP》配套源码是一份非常宝贵的资源,它为深入理解PHP编程语言提供了实践性的支持。PHP(Hypertext Preprocessor)是一种广泛应用于Web开发的开源脚本语言,尤其在服务器端处理HTML时表现出色。源码的学习是...

    细说PHP2笔记

    •Mqrkup是由&lt;或&gt;及字符串组成,如,&lt;p&gt;&lt;/p&gt;; •是一种编程语言,也是用浏览器解释的语言。 CSS基础 CSS是Cascading style sheets的缩写 •是一种用来表现HTML样式的语言; •不能独立使用 •没有html就没有CSS •...

    韩顺平细说servlet笔记

    此外,访问问题可能涉及默认主页设置,可在浏览器管理加载项中调整。 10. **Tomcat目录结构** - **bin**:包含启动和关闭Tomcat的批处理文件。 - **conf**:存储配置文件,如server.xml(配置服务器端口、Host和...

Global site tag (gtag.js) - Google Analytics