String基础面试题 字符池详解

发布时间:2020/04/26| 阅读:

为什么String要被final修饰

被final修饰主要从两个方面来解释就是安全,一个就是高效。因为当你在传参时不需要考虑谁会修改它的值;如果是可变类的话,则有可能需要重新拷贝出来一个新值进行传参,这样在性能上就会有一定的损失。同样的如果你调用方法的时候如果是可变的那么你校验完毕之后值如果发生了修改就会造成错误。

String字符池是什么?有什么作用?

字符常量池的作用其实就是为了缓存字符串来提高我们程序的运行效率。

在我们使用String的时候有两种方式来创建,一种就是直接使用new关键字来创建变量,另外一种就是直接赋值,在我们使用直接赋值的方式时先去字符串常量池中查找是否已经有此值,如果有则把引用地址直接指向此值,否则会先在常量池中创建,然后再把引用指向此值。而new String() 的方式一定会先在堆上创建一个字符串对象,然后再去常量池中查询此字符串的值是否已经存在,如果不存在会先在常量池中创建此字符串,然后把引用的值指向此字符串

比如现在有两个变量

String s1 = "java";
String s2 = "java";

在内存中入下图所示:

img

同时这也是为什么String要被final修饰的原因之一,s1和s2的值引用是同一个,那么如果String是可变的s1的值被修改了s2的值也会被改变,字符池的存在就没有意义了

String 的 intern() 方法有什么含义?

Intern()方法是一个Native方法,作用就是判断当前字符串在字符池中是否存在,如果存在就返回引用,如果不存在就当前String对象的引用地址(堆中)添加到字符串常量池中并返回。下面看几个例子

//直接赋值,会把Java存在常量池中
String a1 = "Java";
//首先会把Golang存在常量池中,然后在会在heap中创建对象并且指向a2
String a2 = new String("Golang");
//使用字符穿拼接会把JavaHtml存储在常量池中
String a3 ="Java"+"Html";
//引用拼接 不调用intern()方法不会存储在常量池中,会把CSS存储在常量池中
String a4 ="CSS"+a1;
//不调用intern()方法不会存储到常量池中,会把Python和Ruby分别存储在常量池中
String a5 = new String("Python")+new String("Ruby");
//不调用intern()方法不会存储到常量池中会把Vue和JS分别存储在常量池中
String a6 = new String("Vue")+"JS";

同时String a2 = new String("Golang");是创建了2个对象,第一个对象是Golang字符串存储在常量池中,第二个对象在JAVA Heap中的 String 对象。

==与equals的区别

==与equals的主要区别是:==常用于比较原生类型,而equals()方法用于检查对象的相等性。 另一个不同的点是:如果==和equals()用于比较对象,当两个引用地址相同,==返回true。 而equals()可以返回true或者false主要取决于重写实现。


📚相关文章