侧边栏壁纸
  • 累计撰写 6 篇文章
  • 累计收到 5 条评论

JAVA中的String面试考点分析

admin
2021-03-09 / 0 评论 / 15 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年03月10日,已超过40天没有更新,若内容或图片失效,请留言反馈。

JAVA中的String面试考点分析

String类型的创建

String类在Java开发中还是常见的,String类型的创建有两种方式

String a = "ABC";
String b = new String("ABC");

然而这两种创建方式里面的学问大有不同。而且这个问题也是一个热门的面试话题。欢迎大家在评论区讨论。

第一种:使用字面量的方式直接创建。JVM首先在栈里面创建一个a的引用,然后检索字符串常量池(String pool,在jdk1.7之后存在堆内存里面,1.7之前存在于方法区里面)里面是否存在这个 “ABC" ,如果字符串常量池里面存在 ”ABC“ ,就会直接返回 ”ABC“ 的引用地址给a,如果不存在,那么就在字符常量池里面创建一个,然后再返回地址。

image-20210301211532126

第二种:使用new的方式直接创建,创建字符串常量时,JVM会首先检查字符串常量池,如果 ”ABC“已经存在常量池中,那么不再在字符串常量池创建该字符串对象,而直接堆中创建该对象的副本,然后将堆中对象的地址赋值给引用b,如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中,然后在堆中创建该对象的副本,然后将堆中对象的地址赋值给引用b。

image-20210301213336309

题目一 创建了多少个对象?

String b = new String("ABC");

个人见解:至少一个,最多两个。如果字符串常量池里面有”ABC",就只在堆里面创建一个,如果没有的话,则创建两个。

new String(“a”) + new String(“b”)

创建了多少个对象? 6个
①用于拼接的new StringBuilder()
②new String(“a”)
③字符串常量池中的"a"
④new String(“b”)
⑤字符串常量池中的"b"
⑥StringBuilder.toString()中的new String(“ab”),注意这里的String并没有在常量池中生成"ab"
总结:

  1. 使用new String(“ab”)会在常量池中会生成"ab";
  2. 使用"A"+"B"+"C"这种字面量加起来的,也会在常量池相加;
  3. 使用new String(“a”) + new String(“b”),或者其中一个字面量,其中一个不是字面量的相加,不会在常量池中生成"ab"。

题目二 是否相等?

String a = "ABC";
String b = new String("ABC");

很明显两者是不相等的,因为A是使用字面量的意思创建的,在常量池里面创建,b则是在堆里面创建,两者当然不一样。

String a = "A"+"B"+"C";
String c = "ABC";
String b = new String("ABC");

这里C是使用字面量的创建方式,虽然是A B C相加,但是Java有优化机制,最后的结果就是在常量池里面生成一个"ABC",然后C创建的时候就会去常量池里面寻找,发现常量池里面存在这一个字符串,然后就会返回这个字符串的引用地址。所以 A==C 是 true,但是和B作比较就是false的

String a = "A"+"B";
String b = "C";
String c = a + b;
String d = new String("ABC");
String e = d;

这里a + b 确实是一个字符串"ABC",但是这是在堆内存里面的,并不是在常量池的。注意和上面的区别。但是我们看第四行,这是一个赋值语句,这个语句就是把d的引用地址赋值一份给e,所以d和e是指向同一个地址。

题目三 ==和equals的区别?

使用==:

基本数据类型(8大类型 byte short char int long float double boolean):比较的就是值是否相等。

引用书类型(类,数组,String等等):比较的是地址值是否相等

使用equals:

String:可以查看源码,发现String类的equals方法被重写了,所以字符串的equals的方法就是判断字符串的内容是否相等。

其他的类:自己写的,如果没有重写equals方法,类就会继承并使用object类的equals比较方法,查看源码可以发现还是用==做比较。所以比较的还是内存中的地址值。

题目四 字符串的intern方法

  • 如果常量池中有,则并不会放入,返回已有的常量池中的对象地址
  • 如果常量池没有,会把对象的引用地址复制一份,放入常量池,并返回常量池中的引用地址
1

评论 (0)

取消