关于java.lang.String理解中的一些难点

java

最近温习java的一些基础知识,发现以往对String对象认识上的一些不足。特汇总如下,主要是帮助记忆,如能对其他朋友有些启发,不胜欣喜。

String在JVM中内存驻留问题

JVM的常量区(Constant Pool)中维持了大部分创建的string (Interned Strings)。举例,

Sring a="ABC";String b="ABC";

当JVM为a赋值时会在常量区生成一个String Constant,当b也赋值为“ABC”时,那么会在常量池中查看是否存在值为“ABC”的常量,存在的话,则把b的指针也指向“ABC”的地址,而不是新生成一个String Constant。

JDK1.6中Interned Strings存储在Permanent Space的常量池中;

JDK1.7中Interned Strings已经不再存储在Permanent Space中,而是放到了Heap中;

JDK8中PermanentSpace已经被完全移除,InternedStrings也被放到了MetaSpace中。

 

 

String.substring()方法

返回新的String对象,JAVA6返回的新对象与原有对象底层共享存储空间char[]数组,通过偏移和长度构造了一个"新"的String,导致substring对象被引用时,原对象即使没有被引用也不能被销毁;JAVA7之后返回的新对象会新建底层的存储空间

 

 

+与concat()的区别

1.  concat是String方法,String重载了“+”操作符(提醒下:Java不支持其他操作符的重载)

2. concat方法在参数为空时返回原字符串,不为空时返回新的String对象;而+在两个操作数都是常量时可能返回内存中已有的Interned String引用,操作数存在变量时必定新建String对象

 

 

对于敏感信息,为何使用char[]要比String更好?

String是不可变的。这意味着一旦创建了字符串,如果另一个进程可以进行内存转储,在GC发生前,(除了反射)没有方法可以清除字符串数据。

使用数组操作完之后,可以显式地清除数据:可以给数组赋任何值,密码也不会存在系统中,甚至垃圾回收之前也是如此。

所以,是的,这是一个安全问题 – 但是即使使用了char数组,仅仅缩小了了攻击者有机会获得密码的窗口,它值针对制定的攻击类型。

 

 

如何通过空白字符拆分字符串

String 的 split()方法接收的字符串会被当做正则表达式解析,

"\s"代表空白字符,如空格" ",tab制表符"\t", 换行"\n",回车"\r".

而编译器在对源代码解析时,也会进行一次字面量转码,所以需要"\\s".

 

String[] strArray = aString.split("\\s+");

 

 

String vs StringBuilder vs StringBuffer

StringBuilder 是可变的,因此可以在创建以后修改内部的值

StringBuffer 是同步的,因此是线程安全的,但效率相对更低

以上是 关于java.lang.String理解中的一些难点 的全部内容, 来源链接: utcz.com/z/390287.html

回到顶部