栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

String面试1

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

String面试1

1、字符串的创建

字面量直接赋值
先去常量池中找有没有这个字符串,有就直接指向常量池中该字符串;没有直接创建

String str1 = "hello" ;
String str2 = "hello" ;
String str3 = "world";


new 创建
new一个字符串时,做了两件事。首先在堆中生成了该字符串对象,然后去看常量池中有没有该字符串,如果有就不管了,没有就往常量池中添加一个

 String str1 = new String("hello");
 String str2 = new String("hello");
 String str3 = new String("world");


在堆中创建三个对象,常量池中两个共5个。
小结:两种创建方式一个在堆中,一个在常量池中。

2、字符串拼接

(1)常量拼接

String str = "hello"+"world";
//两边都是常量,在编译阶段会自动拼接变成
String str = "helloworld";

直接去常量池找 “helloworld”,有就直接指向它,没有就在常量池创建。
(2)有final的拼接

final String str1 = "hello";
final String str2 = "world";
String str3 = str1 + str2;

因为final 修饰的变量是常量,所以在编译期直接会变成

String str3 = "hello" + "world";

再根据常量拼接最终变成

String str3 = "hello" + "world";
3、变量和常量拼接

变量和常量拼接的时候会调用StringBuilder的append方法生成新对象。
情况1:

String str1 = "hello";
String str2 = str1 + "world";


str1在常量池中,world在常量池中,调用StringBuilder的append方法在堆中生成新对象
helloworld,str2指向堆中的helloworld 对象。共生成三个对象,常量池中有 hello 和 world,堆中有 helloworld.
情况2:

String str1 = new String("hello");
String str2 = str1 + "world";


先在堆中创建一个 hello,再把 hello 添加到常量池;然后把 world 添加到常量池,拼接的时候,会在堆中创建一个 helloworld。共4个对象,堆中 hello、helloworld 常量池中 hello world。

4、变量和变量拼接

变量和变量拼接底层也会调用 StringBuilder的append方法生成新对象。
情况一:

String str1 = "hello";
String str2 = "world";
String str3 = str1 + str2;


这段代码,首先会有一个"hello"在常量池中,然后有个"world"在常量池,第三行代码会调用append方法,在堆中生成一个"helloworld"。所以总共有3个对象。
情况二:

String str1 = "hello";
String str2 = new String("world");
String str3 = str1 + str2;


这段代码,首先在常量池中搞一个"hello",然后在堆中new一个"world",同时把"world"也搞到常量池中去,第三步拼接就会在堆中生成一个"helloworld"。所以总共有4个对象。
情况三:

String str1 = new String("hello");
String str2 = new String("world");
String str3 = str1 + str2;


第一行代码创建了两个对象,堆中一个常量池一个,第二行代码也是一样,第三行代码就在堆中创建了一个"helloworld"。所以总共创建了5个对象。

5、intern方法(jdk8)

例一:

String str1 = new String("str")+new String("01");
str1.intern();
String str2 = "str01";
System.out.println(str2==str1); //true


在堆中创建一个str,同时添加到常量池中;再创建一个01,同事添加到常量池中,拼接。
在堆中生成对象str01, str1.intern() 把它的地址值添加到常量池中去;执行String str2 = str01时候,去常量池找 str01,发现常量池中有 x001地址值,为对应的要找的 str01。最终str1指向地址值为 x001 对象,str2 指向地址值为 x001对象。

例二:

String str1 = new String("str")+new String("01");
String str2 = "str01";
str1.intern();
System.out.println(str2==str1); //false


执行第二步时,往常量池中找str01,发现没有,那就添加一个;再执行str1.intern()时,发现常量池中有str01了,就不进行地址值的拷贝了。最终str1指向堆中的str01,str2指向常量池的str01,所以结果是false。
例三:

String str1 = new String("str")+new String("01");
String str2 = "str01";
str1 = str1.intern();
System.out.println(str2==str1);//true

就是把例二的str1.intern()改成str1 = str1.intern(),看看会有什么变化:

本来str1是指向堆中的str01的,然后重新将str1.intern()赋给str1,str1.intern()是指向常量池的,赋给str1后,所以此时str1也是指向常量池。所以结果就是true。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1035859.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号