String字符串的常见题型汇总

String字符串的题型是非常常见的,我个人在牛客网上刷题也遇到过很多次,虽然题目不难,但是如果一些细节不加以注意,就会做错,接下来我将列出常见的几种类型题,并通过内存图解的方式进行一 一解答,如有不对的地方,欢迎指正!(所画内存图解都是基于JDK1.8的,也就是字符串常量池已经移到堆内存中了)

1.字符串常量

String s1="hello";
String s2="hello";
System.out.println(s1==s2);//true

在这里插入图片描述
2.字符串的拼接

String s1="hello";
String s2="world";
String s3="helloworld";
String s4="hello"+"world";
System.out.println(s3==s4);//true
		
String s5=s1+s2;
System.out.println(s3==s5);//false

在这里插入图片描述
对于字符串常量的相加,涉及到编译器优化问题,在编译时直接将字符串合并,而不是等到运行时再合并。也就是说String s4=“hello”+“world” 其实就等同于String s4=“helloworld”。

而String s5=s1+s2;这种情况是变量相加,只能等到运行时才能判定是什么字符串,编译器不会优化,因为编译期怕你对b和c的值有所改变,所以不会直接进行优化。Java对字符串变量的相加是通过StringBuffer实现的,先构造一个StringBuffer里面存放”hello”,然后调用append()方法追加”world”,再将值为”helloworld”的StringBuffer转化成String对象。StringBuffer对象在堆内存中,那转换成的String对象理所应当的也是在堆内存中。

(PS:如果相加后得到的字符串在常量池中没有,则相加后的字符串还会在常量池中进行维护,也就是在常量池中创建一个相同的字符串,并且由堆中的字符串指向常量池中该字符串)

对上面的例子进行改动:

final String s1="hello";
final String s2="world";
String s3="helloworld";
String s4=s1+s2;
System.out.println(s3==s4);//true
		
String s5="world";
String s6=s1+s5;
System.out.println(s3==s6);//false

这是因为s1和s2被final修饰了,属于常量,值不会再改变,所以会进行编译期的优化,也就是String s4=s1+s2;等同于String s4=“helloworld”;而String s6=s1+s5;由于有一个变量没有被final修饰,所以不会进行编译期优化。

3.使用new创建一个字符串对象,会直接在堆中创建,变量所引用的都是这个新对象的地址,但是如果通过new关键字创建的字符串内容在常量池中存在了,那么会由堆再指向常量池的对应字符;但是反过来,如果通过new关键字创建的字符串对象在常量池中没有,那么通过new关键字创建的字符串对象是不会额外在常量池中维护的。

String s1="hello";
String s2=new String("hello");
System.out.println(s1==s2);//false

在这里插入图片描述
4.intern方法(难点!!!)
intern()方法是一个本地方法;当调用intern方法时,如果池中已经包含一个与该String确定的字符串相同equals(Object)的字符串,则返回该字符串。否则,将此String对象添加到池中,并返回此对象的引用。也就是说调用一个String对象的intern()方法,如果常量池中有该对象了,直接返回该字符串的引用(存在堆中就返回堆中,存在池中就返回池中),如果没有,则将该对象添加到池中,并返回池中的引用。

String s1="hello";
String s2=s1.intern();
System.out.println(s1==s2);//true

在这里插入图片描述

String s1=new String("hello");
String s2=s1.intern();
System.out.println(s1==s2);//false

在这里插入图片描述

String s1="hello";
String s2="world";
String s3=s1+s2;		
String s4=s3.intern();
System.out.println(s3==s4);//true

在这里插入图片描述
而我们如果在上面的例子中添加了String s5=“helloworld”;这行语句之后,结果又不一样了

String s1="hello";
String s2="world";
String s5="helloworld";
String s3=s1+s2;
String s4=s3.intern();
System.out.println(s3==s4);//false

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/can_chen/article/details/105973521