Java中字符串的那些事儿

来源:互联网 发布:java bean json 编辑:程序博客网 时间:2024/06/06 02:49

字符串是java中非常常用的一种数据类型,我们通常用String类型的变量(对象)来临时存储一个字符串,关于字符串有几个值得注意的地方,下来我们一起来交流一下。

1、字符串是常量,一旦被赋值就不可以改变,但是其引用是可以改变的。

这句话什么意思呢?开始笔者就觉得很疑惑,比如说我们我们创建一个String类型的变量,例如String s = "Hello World",之后明明可以对s进行赋值操作,比如说s = "Hello Java",这样肯定是没有问题的,但这不是和上面的说法矛盾么?

那么这里我们先仔细分析一下,我们在创建s并为其赋值的时候JVM都做了些什么。需要提醒一下的是,java中的变量存储在栈内存中,而对象是存储在堆内存中,字符串则是存储在方法区的字符串常量池里。所以在执行String s = "Hello World"时JVM首先会在栈内存里开辟一个空间用来存储变量s,然后再在方法区中的字符串常量池查找池内是否存在"Hello World"这个字符串,如果存在,则把该字符串的引用地址给s;不存在的话就新创建该字符串,然后再把该字符串的引用地址给s。


而我们再次对s进行赋值的时候,比如说我们要将字符串"Hello Java"赋值给s,这个时候JVM会直接在方法区中的字符串常量池查找池内是否存在"Hello Java"这个字符串,同样的,如果存在,直接将引用地址给s,不存在创建后再将引用地址给s。所以看上去是变量s的内容变了,但实际上变化的是引用地址,而不是"Hello World"这个字符串变成了"Hello Java",不知道这样说大家能不能看明白,下面用图来说明一下,方便大家理解。


2、String s = "Hello World"String s = new String("Hello World")是不同的。

在前面已经说了String s = "Hello World"的执行过程,这里就不再赘述,上面笔者也说了,当我们用“new”生成一个对象的时候,JVM会在堆内存中开辟一个空间来存储生成的对象,然后将该对象的引用地址给s;同时,JVM还会在字符串常量池里面寻找是否存在字符串"Hello World",这里和String s = "Hello World"执行类似的操作,但是值得注意的是,这里是将"Hello World"的引用地址给在堆中新生成的对象。

我们都知道String类“equals”和“==”的区别,“equals”比较的是字符串的内容是否相等,这个比较容易判断,我们就不多说,现在说一说“==”。如果String s1 = new String("ABC"),String s2 = new String("ABC"),那么s1 == s2的结果是true还是false?

很显然,这里是用的“new”来生成对象,那么将会在堆内存中生成开辟两个空间来存储,而这两个空间的地址肯定不一样,自然s1和s2不会相等,结果也就是false了。

3、字符串如果是两个变量相加,先开辟空间,再进行拼接;如果是两个常量相加,则先拼接,再在字符串常量池中查找拼接后的字符串是否存在。若存在,则直接返回该字符串的引用地址,否则就新创建,再返回。

举个例子来说明:

String s1 = "Hello"

String s2 = " World"

String s3 = "Hello World"

现在判断(1)s3 == s1 + s2

                       (2)s3 == "Hello" + " World"

分析:s1和s2是两个变量,按照上面说的,两个变量相加,先开辟空间,再进行拼接。既然开辟了空间,肯定地址不会和给s3的地址一样,所以(1)为false;而"Hello"和" World"就是两个字符串,字符串是常量,常量是先拼接,然后寻找,如果寻找不到再创建、开辟空间。所以(2)会现将"Hello"和" World"拼接为"Hello World",然后在字符串常量池中寻找有没有内容和它一样的字符串。恰好这里就有这么一个,而且这个字符串的引用地址还给了s3,所以(2)的结果自然就为true。

4、String、StringBuffer和StringBuilder的区别

(1)String的内容是不可变的,而StringBuffer和StringBuilder的内容是可变的。

(2)StringBuffer是线程安全的,所以它的效率较低;而StringBuilder是非线程安全的,效率较高。

5、在需要传入参数的方法中,基本数据类型的形式参数并不会影响实际参数;而引用数据类型的形式参数会直接影响实际参数。但是String是个例外,它的效果和基本类型一样。


原创粉丝点击