Java字符串为何不可变

String是Java中一个不可变的类,所以它一旦被实例化就无法被修改。不可变类的实例一旦创建,其成员变量的值就不能被修改。不可变类有很多优势。

一、字符串池

字符串池是Java运行环境方法区中的一部分特殊存储。当一个字符串被创建之时,首先会去这个字符串池中查找,如果找到直接返回对该字符串的引用。下面的代码只会在堆中创建一个字符串:

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

如果字符串可变的话,当两个引用指向指向同一个字符串时,对其中一个做修改就会影响另外一个。【请记住该影响,有助于理解后面的内容】

注意:
String s = new String(“abc”);创建了几个对象,有两种情况:
1.如果字符串常量池中有字符串abc,那么只会在内存中创建一个对象(此对象是不能重复的);
2.如果字符串常量池中没有字符串abc,那么在字符串常量池中创建一个内容为abc的对象,但是遇到了new关键字,则还是会在内存(不是常量池)中创建一个对象,然后将对象返回给引用s,特别注意s不是一个对象。
说明:
Java方法区中的字符串常量池,由String类维护。执行语句String s="abc"时,首先查看字符串池中是否存在字符串"abc",如果存在则直接将"abc"赋给s,如果不存在则先在字符串常量池中新建一个字符串"abc",然后再将其赋给s。

二、缓存Hashcode

Java中经常会用到字符串的哈希码(hashcode)。例如,在HashMap中,字符串的不可变能保证其hashcode永远保持一致,这样就可以避免一些不必要的麻烦。这也就意味着每次在使用一个字符串的hashcode的时候不用重新计算一次,这样更加高效。
在String类中,有以下代码:

private int hash;//this is used to cache hash code. 

以上代码中hash变量中就保存了一个String对象的hashcode,因为String类不可变,所以一旦对象被创建,该hash值也无法改变。所以,每次想要使用该对象的hashcode的时候,直接返回即可。

三、使其他类的使用更加便利

如下代码:

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";
}

如果字符串可以被改变,那么以上用法将有可能违反set的设计原则,因为set要求其中的元素不可以重复。上面的代码只是为了简单说明该问题,其实String类中并没有value这个字段值。

四、安全性

String被广泛的使用在其他Java类中充当参数。比如网络连接、打开文件等操作。如果字符串可变,那么类似操作可能导致安全问题。因为某个方法在调用连接操作的时候,它认为会连接到某台机器,但是实际上并没有(其他引用同一String对象的值修改会导致该连接中的字符串内容被修改)。可变的字符串也可能导致反射的安全问题,因为它的参数也是字符串。代码示例:

boolean connect(string s){
    if (!isSecure(s)) { 
        throw new SecurityException(); 
    }
    //如果s在该操作之前被其他的引用所改变,那么就可能导致问题。   
    causeProblem(s);
}

五、不可变对象天生就是线程安全的

因为不可变对象不能被改变,所以它们可以自由地在多个线程之间共享。不需要任何同步处理。总之,String被设计成不可变的主要目的是为了安全和高效。所以,使String是一个不可变类是一个很好的设计。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容

  • 进入【知己空间】,付了266,却迟迟不开课。每天在群里也就领领红包,却失去了曾经抢红包时的那股冲动与兴奋,因为红包...
    KSP信仰哥哥阅读 375评论 0 6
  • 亲子日记第四十天 今天是星期二,这几天可能是由于爸爸在家的缘故,晚上睡的有点晚,早上自己起不来了,6点2...
    福宁妈妈阅读 126评论 0 0
  • 没有一帆风顺的事。 我给你一个期限,一个允许自己软弱的机会。如果错过 那就是错过。 你可以接单,是的,我也会难得唱...
    行一馆阅读 185评论 0 0
  • 2018年8月18日 姓名:潘红军 公司 :扬州市方圆建筑工程有限公司 【日精进打卡第209天】 南京第349期...
    5119a64ee3ab阅读 64评论 0 0