java小白-String常见误区

1.String两种实例化区别

首先,我们来看最常见的,也是比较推荐的实例化方法:

String name="ZhangSan";//实例化String对象。这是最直接,最常见的实例化方法,直接赋值的方式

当然,另一种方法也是我们实例化普通对象时最常见的,使用String类构造器实例化:

String name=new String("ZhangSan");

二者区别:我们首先需要知道,每一个字符串,其实就是一个String类的匿名对象,匿名对象也就是已经开辟了堆内存的空间而且可以直接使用的对象。(比如:System.out.println("name".equals(name));,结果为true,这里的字符串"name"本身就是一个匿名对象,所以 可以调用equals方法)

1.1   对于String name="ZhangSan",实际上就是把一个在堆内存中开辟好了的空间的使用权交给了name这个对象,也就是 相当于将"ZhangSan"这个对象的地址,给了name,相当于c语言中的指针引用。

 

这种方式有个好处就是,当一个字符串已经被一个名称所引用,则以后再有相同的字符串声明的时候,不会再重新开辟空间,如下:

//声明三个字符串变量,每个变量内容都是一样的

String name1="ZhangSan";

String name2="ZhangSan";

String name3="ZhangSan";

System.out.println("比较结果:"+(name1==name2)+(name1==name3)+(name2==name3) );  结果是true、true、true。补充一点,字符串比较如果使用“==”,则实际上比较的是其内存地址数值,也就是其地址。说明,虽然表面上声明了三次,但是name1、name2、name3都指向了字符串"ZhangSan",如图:

这个现象涉及到JVM底层实现,String类所采用的设计模式为共享设计模式。在JVM底层实际上存在一个对象池(不一定只保存String对象),当代码中使用了直接赋值的方式定义了一个String类对象时,会将此字符串对象所使用的匿名对象入池保存,而后如果还有其他String类对象也采用直接赋值的方式,并且设置同样内容的时候,那么不会新开辟堆内存空间,而是使用已有的对象进行引用分配。

1.2 对于String name=new String("ZhangSan");  前边我们说过一个字符串就是一个匿名对象,如果使用new关键字的话,不管如何都会再开辟一个新的空间,但此时空间内容还是"ZhangSan"。所以使用这个方法,实际上是开辟了两个内存空间,但真正使用的只是一个使用关键字new开辟的空间,另一个是垃圾空间,如图:

二者虽然有所区别,但是在实际开发中,大多数情况一定是采用法一,也就是直接赋值的方式。

2.需要注意的是:字符串的内容不可改变。

看如下代码:

String str="hello";//声明字符串

str=str+"world!";//修改字符串

System.out.println(str);

运行结果是:hello world!看似这里的字符串发生了改变,其实,内容并不是真的修改了,一个String对象内容的改变实际上是通过内存地址的“断开-连接”变化完成的,而字符串本身内容并没有变化。如图:

所以,在日后开发中,如果修改字符串内容可以通过StringBuffer类完成,不要通过循环来改变其内容,每次改变都意味着一次断开连接,会降低代码性能。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值