继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

涨知识丨Java 中的 String 真的是不可变吗?

慕尼黑5497867
关注TA
已关注
手记 378
粉丝 23
获赞 77

我们都知道 Java 中的 String 类的设计是不可变的,来看下 String 类的源码。

public final class String

implements java.io.Serializable, Comparable, CharSequence {

/** The value is used for character storage. */

private final char value[];

/** Cache the hash code for the string */

private int hash; // Default to 0

// …

}

可以看出 String 类是 final 类型的,String 不能被继承。其值 value 也就是对字符数组的封装,即 char[],其值被定义成 private final 的,说明不能通过外界修改,即不可变。

涨知识丨Java 中的 String 真的是不可变吗?

String 真的 "不可变 " 吗?

来看下面这个例子。

String str=“Python”;

System.out.println(str); // Python

str=“Java”;

System.out.println(str); // Java

str=str.substring(1);

System.out.println(str); // ava

你有可能会问:str 不是由 Python 变成 Java 了吗?然后通过 substring 方法变成 ava 了吗?

这其实是初学者的一个误区,从上面看 String 的结构可以得知字符串是由字符数组构成的,str 只是一个引用而已,第一次引用了 “Python”,后面变成了 “Java”,而 substring 也是用 Arrays.copyOfRange 方法重新复制字符数组构造了一个新的字符串。

Java中的String真的是不可变吗?_

所以说,这里的字符串并不是可变,只是变更了字符串引用。

涨知识丨Java 中的 String 真的是不可变吗?

String 真的真的真的 "不可变 " 吗?

上面富贵论坛的例子肯定是不可变的,下面这个就尴尬了。

String str=“Hello Python”;

System.out.println(str); // Hello Python

Field field=String.class.getDeclaredField(“value”);

field.setAccessible(true);

char[] value=(char[])field.get(str);

value[6]=‘J’;

value[7]=‘a’;

value[8]=‘v’;

value[9]=‘a’;

value[10]=’!’;

value[11]=’!’;

System.out.println(str); // Hello Java!!

通过反射,我们改变了底层的字符数组的值,实现了字符串的 “不可变” 性,这是一种骚操作,不建议这么使用,违反了 Java 对 String 类的不可变设计原则,会造成一些安全问题。

涨知识丨Java 中的 String 真的是不可变吗?

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP