java中字符串数组#clone做了什么?

hotspot jdk1.8:

// ...
    /**
     * 可以使用return (strings != null) ? strings.clone() : new String[0]
     * 达到相同的效果(深度拷贝字符串数组).
     */
    private String[] copyStrings(String[] strings) {
        String[] arr = null;
        if (strings != null) {
            int len = strings.length;
            arr = new String[len];
            if (len > 0) {
                System.arraycopy(strings, 0, arr, 0, len);
            }
        }

        return ((arr != null) ? arr : new String[0]);
    }
// ...

如上,需要深拷贝字符串数组,防止调用方修改.

这里clone()的行为是来源于Object对象的,貌似是拷贝的StringTable中的字符串字面量(不是字符串对象)的引用地址(值传递),不知道是不是这样的?

阅读 2.1k
2 个回答

在 Java 中,String 是不可变对象(immutable),也就是说,创建了一个 String 对象之后,它的值就不能被修改。这意味着,如果我们对某个字符串进行拷贝操作,实际上需要拷贝的是该字符串底层所维护的字符数组,而不是拷贝该字符串对象本身。

String 类提供了 clone() 方法,可以进行浅克隆,它将克隆当前对象的一个副本并返回。对于 String 对象而言,clone() 返回的是这个对象的地址。由于 String 对象是不可变的,因此在调用 clone() 时,并不会复制原始字符串中的字符数组,而是直接引用已有的字符数组,从而达到了所谓的“浅拷贝”。

至于 StringTable,它是字面量字符串(literal string)存储区域的一个缓存区域,主要用来减少内存使用,加快重复字符串的访问速度。strings.clone() 并不会涉及到 StringTable 的操作,仅仅对输入字符串数组进行浅拷贝操作并返回新数组,从而避免了调用方对该数组的修改影响到原始数组的问题。
你的使用System.arraycopy进行拷贝是进行了深拷贝

链接: String类介绍

如果只是为了防止调用方修改,可以转换成不可修改的(unmodifiableList),拷贝成本太高了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏