Java基础面试 - String

0.String是最基本的数据类型吗?
不是,基本数据类型包括byte、int、char、long、float、double、boolean和short

1.String一旦声明不可以被改变?
因为字符串操作频繁,所以Java对其使用了字符串常量池来管理。简单的说就是如果池子里有就直接用,没有就创建再用。

String str = "123";
 str = "456";

在这里插入图片描述

2.String str = new String(“abc”);创建了几个对象?
可能是一个,也可能是两个。如果有代码在常量池中已经创建了"abc"(String a = “abc”;)就直接使用,没有就创建。而 new String()是在堆内存中开辟了一块新的空间。
"abc"是在常量池中创建的对象
在这里插入图片描述

3.输出结果

String s1="abc";
String s2="abc";
System.out.println(s1==s2);  //true,两个变量指向同一常量池中的地址
System.out.println(s1.equals(s2)); //false,字符序列相同(白话:内容一样)

4.输出结果

String s1=new String("abc"); 
String s2="abc";
System.out.println(s1==s2);  //false 地址值不同
System.out.println(s1.equals(s2)); //true 内容一样

5.输出结果

String s1="a"+"b"+"c";
String s2="abc";
System.out.println(s1==s2);  //s1到池子中也是"abc",地址一样
System.out.println(s1.equals(s2));  //内容一样

6.输出结果

String s1="ab";
String s2="abc";
String s3=s1+"c";
System.out.println(s3==s2);   //false 
System.out.println(s3.equals(s2)); //true 内容一样

s3解释:因为常量池的字符串不可以被改变,那就意味着每一个字符串都要在常量池存在一份,这样对内存的开销是很大的,于是用到了拼接对象StringBuffer,而s3的地址等于的是StringBuffer的地址值,和s2指向字符串常量池中的"abc"地址不一样

7.输出结果

final String str1 = "aaa"; 
final String str2 = "bbb";
String str3 = "aaabbb";
String str4 = str1 + str2;  //拼接后为aaabbb,常量池中存在,直接引用
System.out.println(str3 == str4); //true

8.String s = “Hello”;s = s + ” world! 原始的s内容变了嘛?

String s = "Hello";     //s指向常量池中 hello
s = s + "world!";   //创建StringBuffer拼接,s = StringBuffer的地址
//内容没有改变,常量池中依然存在hello,只不过s所指向的地址改变了

9.String和StringBuffer的区别
String一旦声明不可被改变,存放在字符串常量池中,有就直接用,没有就造。所以当拼接的时候,会创建很多,创建后指向也会发生变化,对内存开销很大。
StringBuffer的出现解决了上面的问题,每次拼接都会对本身进行操作,而不是生成新的对象,再改变对象引用。
同时new String(“123”).equals(new String"123") 为true,因为String类里面重写了equals方法,而StringBuffer(“123”).equals(new StringBuffer(“123”))结果为false,StringBuffer没有重写equals方法。

10.StringBuffer和StringBuilder的区别 StringBuilder线程安全 StringBuffer线程不安全