java定义字符串的两种方式的比较

大家都知道,java定义字符串有两种方式。

1.直接赋值

输出结果

2.构造方法实例化

输出结果

两种方式的区别比较

第一种直接赋值定义

“==”虽然是一种字符串的比较,但是它实际上比较的并不是字符串的内容,而比较的是它们所在的内存地址的数值。可能会有疑惑,字符串的直接赋值,会产生一个新的堆内存空间,那么这里应该产生了三块堆内存空间,并且有不同的三个内存地址才对,但这里为什么会出现str1和str2和str3的内存地址是相同的呢?

第一种字符串的直接赋值方式,会给字符串赋予一个“名字”(其实就是堆内存的地址),并且开辟一段新的堆内存(存数据)。

那为什么这里会出现str1,str2,str3同时指向同一块堆内存?

因为JAVA有一个共享设计池(常量池)的概念

什么是共享设计模式?

在JVM底层实际会存在一个对象池,在用户通过直接赋值的方式定义了字符串时,这时候该字符串对应的匿名对象(在上述案例中就是791202.com和791202.cn,字符串常量就是对应的String类的匿名对象)自动“入池保存”,倘若后续过程中用户再次直接赋值定义了字符串并且还使用了相同的内容,那么将不再开辟新的堆内存,而是令其指向原来已经入池的对象进行引用。

因为字符串的值一旦设定将无法改变,因此,JAVA的设计者认为共享的设计方式,可以带来更高的效率。

第二种构造方法实例化

看到这里就已经很清楚构造方法实例化这种方式比较于直接赋值的缺陷所在,多开辟了一块堆内存,存在垃圾问题。

s1因为new关键字存在,就一定会去堆内存中开辟空间存放字符串,接着s2直接赋值定义字符串时,由于常量池存在,故不会创建新的字符串。我们说过==符号在用于引用数据类型时,比较的是两者的地址值,前者在堆内存中有指向,后者没有,因此结果会得到false。

总结

构造方法实例化字符串会存在一部分垃圾空间,便是堆内存中重复创建的字符串字段,因此直接赋值的方式确实优于构造方法的方式,因此字符串在使用时都使用的是直接赋值的方法。

0

发表评论

邮箱地址不会被公开。