Java中String类常见问题介绍
在java中,字符串是一个类,对于string类来说,String对象是不可变的,String对象看似会修改String对象的方法实际上都是创建了一个全新的String对象。
当然,在我们的学习中,我们可能会遇到关于String类的一些问题,下面,列出几种常见问题
对于String类对象地址引用地址比较的问题
在面对这个问题的时候,首先要明白常量池这个概念
String类的设计使用了共享设计模式
在JVM底层实际上会自动维护一个对象池(字符串常量池)
如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存
到这个对象池之中.
如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用
如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用。
对于String类的引用对比来说,大致上分为以下三点
1,全是字符串或者字符串加常量,就会在编译期间直接处理,并放在常量池,返回常量值中字符串的引用
例如
String str = “abcdefg”;
String str1 = “abc” + “defg”;
此时比较str 和 str1的地址会发现,两个引用的地址是相同的, 这里面发生的情况大致是这样的,在编译期间,直接赋值时,str被赋值为abcdefg;此时abcdefg会被放到常量池中,当要生成str1时,此时系统会发现在常量池中有abcdefg,此时就会直接返回abcdef在常量池中的引用;此外,如果拼接的是字符串和常量,也会发生如上过程
2,常量加new 编译期间无法解决,所以不会在编译期间直接处理,所以加new方法的地址与直接字符串常量的地址不同
例如
String str = “abcdefg”;
Strign str1 =new String(“defg”);
此时因为new的关系,在编译期间并不能处理,所以无法进行对比,因此当对比这两个引用时,会发现地址并不相同
当然,除了纯粹的·new一个与放入常量池字符相同的String对象外,我们还可能会遇到这种情况
String str = “abcdefg”;
String str1 = “adcd” + new String(“efg”);
就像上面所说的只要有new,就会产生新的对象,在这个例子中会发生这样的过程,首先,直接赋值str ,会把”abcdefg放到常量池中去,紧接着,在生成str1的时候,先会把"abcd"放进常量池中,后面因为要生成一个新的对象,编译期间无法识别,所以此时只能等到运行期了,运行期开始,先新生成了一个String类”efg“对象,由于String类的不可变性,因此只能再新一个新的Sting对象用来储存”abcd" + “deg”,并且将这个引用返回给str1
3,常量加变量,或者两个变量,也会因为编译期间无法识别,导致只有在运行时才会新建对象,返回与放在常量池中不同的引用;
例如
String str = “abcdefg”;
String str1 = “abcd”;
String str2 = “efg”;
String str3 = str1 + str2;
除此之外,还有String类与StringBuffer类与StringBuilder类的关系
String类的对象是不可变的,那么在需要连续更改一个String引用对象的值时必然会产生很多的新String类对象,在我们实际使用中真的会如此吗?其实并不是,在底层,编译器会为我们自己动优化,在编译时先会创建StringBuilder,用StringBuilder对象去生成String对象,因为想比与String对象而言,StringBuilder对象在定义后可以更改,并且StringBuilder拥有与String类几乎完全相同甚至更多的库函数支持
String ,StringBuilder ,StringBuffer三个的区别和联系
1,String的内容不可修改,StringBuffffer与StringBuilder的内容可以修改.
2,StringBuffffer与StringBuilder大部分功能是相似的
3,StringBuffffer采用同步处理,属于线程安全操作;而StringBuilder采用异步处理,属于线程不安全操作。