zoukankan      html  css  js  c++  java
  • 为什么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.不可变对象自然是线程安全的:

    因为不可变对象不能更改,所以可以在多个线程之间自由共享。这消除了进行同步的要求。

    总之,字符串是为了效率和安全原因而不可变的。这也是为什么在很多情况下首选类是不可变类的原因。

  • 相关阅读:
    for循环
    条件语句练习
    语句
    语言基础
    python -- 异步IO 协程
    转--python -- 收发邮件
    hive vs hbase
    postgresql 常用速查
    转--利用hexo搭建个人静态博客
    转- --python 3 编码
  • 原文地址:https://www.cnblogs.com/zjiacun/p/8290238.html
Copyright © 2011-2022 走看看