String在Java中是个不可更改的类。一个不可更改的类简单来说就是这个类的所有实例是不可以更改的。所有的实例信息在创建的时候被初始化而且信息是不可以更改的。不可更改的类有很多好处。
这篇文章总结了为什么String被设计成不可以改变的。一个好的回答需要深入理解内存、同步和数据结构等。
1、 字符串池的需要
字符串池(字符串内部池) 是在方法区域的特殊区域。当一个string被创建如果这个string已经在内存里面存在了,那个存在的string的引用被返回,而不是创建个新的对象和返回它的引用。
下面的代码将在堆上创建一个string对象。


String string1 = "abcd";
String string2 = "abcd";

如果这个string是可以改变的,通过一个引用改变一个string将导致另一引用指向错误的值。
2、 缓存哈希值
在Java中,string的哈希值经常被用。举个例子,在HashMap中。保持不变,可以保证总是返回相同的哈希值。所以它可以被缓存而不用担心被改变。 这意味这不需要在使用的时候每次都计算哈希值。
这将更高效。
在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";

在这个例子中,如果String是可以改变的,如果它的值被改变这将违反了Set的设计(Set不可以包含重复的元素)。这个例子是为了简化设计的,在实际的String类中没有value 属性。

4、 安全
String 在很多java的类中,网络连接中,打开的文件中经常被作为参数使用。如果String是可以改变的,一个连接或者文件将有可能被改变,这将导致严肃的安全威胁。这个方法认为它正连接到一个机器,但是实际上不是。易变的strings将在反射或者作为参数将导致安全问题。
下面是代码实例:


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、 不变对象是自然线程安全
因为不可变对象是不可以改变的,它能够被多个线程自由的共享。这消除了同步。
总结,String被设计成不可以更改的是为了效率和安全。这也是为什么现在很多不可以改变的类。

三、为什么String在Java中是不可更改的的更多相关文章

  1. 为什么 String 在 Java 中是不可变的(终极答案)

    为什么 String 在 Java 中是不可变的(终极答案) 我们可以从2个角度去看待这个问题: 1.为什么要设计成不可变2.如何保证不可变? 1.为什么设计不可变? 1.String对象缓存在Str ...

  2. 为什么 String 在 Java 中是不可变的?

    我最喜欢的 Java 面试问题,很棘手,但同时也非常有用.一些面试者也常问这个问题,为什么 String 在 Java 中是 final 的.字符串在 Java 中是不可变的,因为 String 对象 ...

  3. 五、String在Java中是传“引用”

    这个是Java的经典问题.许多类似的问题在stackoverflow被提问,有很多不正确或不完备的答案.如果不想太多你会认为这个问题比较简单.( The question is simple if y ...

  4. 从缓存入门到并发编程三要素详解 Java中 volatile 、final 等关键字解析案例

    引入高速缓存概念 在计算机在执行程序时,以指令为单位来执行,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入. 由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这 ...

  5. String是java中的基本数据类型吗

    1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. Ja ...

  6. java中的堆、栈、常量池以及String类型的两种声明

    参考自http://blog.sina.com.cn/s/blog_798b04f90100ta67.html http://www.cnblogs.com/fguozhu/articles/2661 ...

  7. Java中String, StringBuilder和StringBuffer

    Java中常用来处理字符串的类有三个: String, StringBuffer和StringBuilder. 区别 三者都继承自CharSequence接口, 首先说明三者间主要区别 String字 ...

  8. Java学习笔记(一)——关于java中的String类

    [前面的话] 毕业将近6个月了,试用期也快要过去了,期待接下来的日子.在金融类性质的机构,最痛苦的是也许就是大部分系统外包,所以比较少写代码,在这六个月中只写了1个月左右的代码,然后每天都在做一些比较 ...

  9. Java中String类的特殊性

    java中特殊的String类型 Java中String是一个特殊的包装类数据有两种创建形式: String s = "abc"; String s = new String(&q ...

随机推荐

  1. ubuntu下的fdisk用法

    Linux下的fdisk功能是极其强大的,用它可以划分出最复杂的分区,下面简要介绍一下它的用法: 对 于IDE硬盘,每块盘有一个设备名:对应于主板的四个IDE接口,设备名依次为:/dev/hda,/d ...

  2. 记录规则 – 销售只能看到自己的客户,经理可以看到全部

    OpenERP中的权限管理有四个层次: 菜单级别: 即,不属于指定菜单所包含组的用户看不到该菜单.不安全,只是隐藏菜单,若用户知道菜单ID,仍然可以通过指定URL访问 对象级别: 即,对某个对象是否有 ...

  3. windows2003密码忘记了该如何处理

    如果你有sql   server的管理员帐号,并且可以登录,尝试用下面的方法:         --用管理员连接sql,在查询分析器中执行:         --添加用户     exec   mas ...

  4. servlet ServletConfig ServletContext

    ServletConfig对象 在Servlet的配置文件中,可以使用一个或者多个<init-param>标签为servlet配置一些初始化参数. 当servlet配置了初始化参数后,we ...

  5. TaskMapper

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-/ ...

  6. Apache POI – Reading and Writing Excel file in Java

    来源于:https://www.mkyong.com/java/apache-poi-reading-and-writing-excel-file-in-java/ In this article, ...

  7. Mint17 一些安装备忘

    1,中文输入法: sudo apt-add-repository ppa:fcitx-team/dailybuild-fcitx-master sudo apt-get update sudo apt ...

  8. Java虚拟机学习 - 对象引用强度 ( 8 )

    无论是通过计数算法判断对象的引用数量,还是通过根搜索算法判断对象引用链是否可达,判定对象是否存活都与“引用”相关. 引用主要分为 :强引用(Strong Reference).软引用(Soft Ref ...

  9. Linux Pin Control 子系统

    Pin Control Subsystem是Linux内核抽象出的一套用于控制硬件引脚的一套子系统. 1.源文件列表 源码位于linux/drivers/pinctrl目录下,源文件列表如下: 文件名 ...

  10. 信号的捕捉与sigaction函数

    一.内核如何实现信号的捕捉 如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号.由于信号处理函数的代码是在用户空间的,处理过程比较复杂,举例如下: 1. 用户程序注册了SI ...