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中的字符串字面量(不是字符串对象)的引用地址(值传递),不知道是不是这样的?
如果只是为了防止调用方修改,可以转换成不可修改的(unmodifiableList
),拷贝成本太高了。
在 Java 中,String 是不可变对象(immutable),也就是说,创建了一个 String 对象之后,它的值就不能被修改。这意味着,如果我们对某个字符串进行拷贝操作,实际上需要拷贝的是该字符串底层所维护的字符数组,而不是拷贝该字符串对象本身。
String 类提供了 clone()
方法,可以进行浅克隆,它将克隆当前对象的一个副本并返回。对于 String 对象而言,clone()
返回的是这个对象的地址。由于 String 对象是不可变的,因此在调用 clone()
时,并不会复制原始字符串中的字符数组,而是直接引用已有的字符数组,从而达到了所谓的“浅拷贝”。
至于 StringTable,它是字面量字符串(literal string)存储区域的一个缓存区域,主要用来减少内存使用,加快重复字符串的访问速度。strings.clone()
并不会涉及到 StringTable 的操作,仅仅对输入字符串数组进行浅拷贝操作并返回新数组,从而避免了调用方对该数组的修改影响到原始数组的问题。
你的使用System.arraycopy
进行拷贝是进行了深拷贝
问题内容: 我是一名刚从C ++转到Java的学生。 在Java中,为String和Char数组定义单独的数据类型的主要原因可能是什么? 两者有什么区别? 由于我只学习过C ++,所以直到现在我仍对它们有同感。请尽可能澄清。 问题答案: 是一成不变的。数组不是。字符串是在下面用char数组实现的,但是每次您尝试对其进行修改(例如,使用串联,替换等)时,它都会为您提供一个 新 对象。 因此,它表现为
问题内容: 在android / java中,我试图用替换某些字符串中的空格,但似乎不起作用。我做错了吗? 问题答案: 对象是不可变的,因此该方法不会更改字符串,但会创建一个新的字符串,您必须重新保存它:
问题内容: 我想知道a 是否是集合。我读过一些,但仍然很困惑。 问题答案: 字符串是 代表字符序列的 不可变 对象 (是String实现的接口之一)。与char数组和char集合的主要区别:无法修改字符串,无法(忽略反射)添加/删除/替换字符。 在内部,它们由具有 偏移量* 和 长度 的 char数组 表示 (这允许使用相同的char数组创建轻量级子字符串)。 * 例如:[‘F’,’o’,’o’,
问题内容: 我有阵列 转换为字符串: 串: 以及如何将此字符串转换回数组? 问题答案: 尝试我的stringToDeep()方法转换回Array。
问题内容: 我有一个; 我想转换为字符串数组。我该怎么做?有内置的Java函数吗?可以手动完成,但是我正在搜索Java内置函数。 我想要一个数组,其中字符串的每个字符都是一个字符串。像char’n’现在将是存储在数组中的字符串“ n”。 问题答案: 要开始你的作业,请在正则表达式上拆分字符串,该表达式可以为空字符串: 产生数组: 留空的第一条目留给读者练习:-) 注意:在Java 8中,不再包含空
为什么数组不相等?我希望返回原始的字节数组。