String字符串处理常见的面试题总结

首先,我们要先了解常量池的概念,常量池在java中用于保存在编译期已确定的,存在于已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = “str”这种申明方式;当然也可扩充,执行器产生的常量也会放入常量池,故认为常量池是JVM的一块特殊的内存空间。

问题一:
String是最基本的数据类型吗?
基本数据类型包括byte、int、char、long、float、double、boolean和short。
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类,或者用StringBuffer类。前者效率高,后者支持线程同步。

问题二:

final String str1 = "aaa";    
final String str2 = "bbb";    
String str3 = "aaabbb";    
String str4 = str1 + str2;    
System.out.println(str3 == str4);//true 

解析:
因为str1与str2都定义成了常量,在编译时就已经确定,编译时就会将变量替换为常量,等同于 str4 = “aaa”+”bbb”,因此不产生新的对象。

问题三:

String s = new String("abc");   
String s1 = "abc";   
String s2 = new String("abc");   

System.out.println(s == s1);   
System.out.println(s == s2);   
System.out.println(s1 == s2);

解析:
第一句执行后内存中有两个对象,而不是一个。一个由new String(“abc”)中的”abc”在字符串常量池生成一个值为”abc”的对象;第二个由new在堆里产生一个值为”abc”的对象,该对象完全是String Pool里的”abc”的一个拷贝。变量s最后指向堆中产生的”abc”对象;

第二句执行时,变量s1先去String Pool找是否有值为”abc”的对象,很显然在上一步中java已经在String Pool里生成一个”abc”对象了,所以s1直接指向String Pool中的这个”abc”;

第三句中又有一个new,首先会去字符串常量池中找“abc”,若能找到则直接获取地址,不再创建新的常量。在java中凡遇到new时,都会在堆里产生一个新的对象。因此,该句执行后堆里又多了一个”abc”对象,这与执行第一句后生成的”abc”是两个不同的对象,s2最后指向这个新生成的对象。
因此,执行后面的打印语句的结果是三个false 。

问题四:

String hello = "hello";   
String hel = "hel";   
String lo = "lo";   
System.out.println(hello == "hel" + "lo");   
System.out.println(hello == "hel" + lo); 

解析:
前三句在String Pool里分别产生“hello”、“hel”、“lo”三个常量字符串对象。
当做第一个加法连接时,+号两边都是常量字符串,”hel” + “lo”在编译时就变成了“hello”,java就会将两者拼起来后到String Pool里找与之相等(用equals)的字符串,若存在则将其地址返回;不存在则在String Pool里新建一个常量对象,其值等于拼接后的字符串,并将其地址返回。

而第二个+号两边有一个是变量,此时,java会在堆里新建一个对象,其值是两字符串拼接后的值,此时返回的地址是堆中新对象的地址。
所以,第一句做+连接后返回String Pool中“hello”的地址,显然与变量hello的地址相等; 第二句返回的是堆中地址,显然与变量hello的地址不等;

问题五:类似于问题四:

public class Test { 
   public static void main(String[] args) { 
       final String str1 = "HelloWorld";
       final String str2 = "Hello" + "World"; 
       System.out.println(str1 == str2);//true 
       final String str3 = "Hello" + String.valueOf("World"); 
       System.out.println(str1 == str3);//false 
  }
 }

解析:
str3需要通过valueOf方法调用之后才能确定。而不是在编译时确定。

问题六:
在Java中String是不可变的和无法改变的,有什么好处?
1,可以使用字符串池来存储字符串,提高存储效率。
2,增加安全性,在存储一些敏感信息,如数据库用户名,密码等是,黑客不能改变它的值。java的类加载器加载类时,字符串的不变性可以确保正确的类被加装。
3,由于String是不可变的,它是安全的,在多线程环境下,我们不需要任何同步。

    原文作者:nwpu_geeker
    原文地址: https://blog.csdn.net/nwpu_geeker/article/details/78701343
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞