Java中两种创建字符串对象的区别对比与面试题
目录
前言
本文介绍两种创建字符串对象的区别对比
一、 两种创建字符串对象的区别对比与面试题
1、创建字符串对象的两种方式有什么区别 ?
创建字符串对象的两种方式有什么区别 ? 1).双引号直接创建(知道内容直接"") : 在常量池维护 2).通过构造方法new出来的字符串对象(不知道就new String创建) : 在堆内存有自己独立的内存空间 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 常量池特点: 当我们使用 "" 双引号创建字符串对象的时候,会检查该数字在常量池是否存在 不存在:创建 存在:复用
⚡面试题1⚡
public static void method(){ String a="abc"; String b="abc"; System.out.println(a==b); //这里输出是true}
/* 原因:a先在常量池创建字符串abc,然后b又要创建字符串abc,但发现常量池里面有,所以就会直接复用这个abc给b,它们指向了同一个地址值所以判断的时候是true */
⚡面试题2⚡
public static void method2(){ String s1="abc"; String s2=new String("abc"); System.out.println(s1==s2); //false //这里创建了两个字符串对象,一个是常量池里面abc,一个是堆内存里面的abc }
/* 原因: 1.s1先是在常量池创建了字符串abc//第一个字符串对象 2.s2因为 new关键字 在堆内存开辟空间如0x001,"" 双引号去到常量池找字符串abc,发现有所以复用这个abc,把这个abc拷贝过来给0x001这个地址值,所以这个地址值存储了副本abc //第二个字符串对象 3. s1存储的常量池里面的,s2存储的是地址值,所以false */
(这个图和上面的无关,同个道理而已)
⚡面试题3⚡
public static void method3(){ String s1="abc";String s2="ab";String s3=s2+"c";System.out.println(s1==s3); //false}
/*原因: 1.s1在常量池创建 字符串abc 2.s2在常量池创建 字符串ab 3.s3先在常量池创建字符串c,然后在堆内存里面创建StringBuilder对象(这是一个独立的地址值如0x001),调用append方法拼接成字符串abc,然后调用toString方法把StringBuilder转为String类型,再传给s3(新的地址值) 4.s1是常量池,s3是堆内存地址值,所以是false */* 扩展: /* 字符串+号拼接的原理:1.系统会 [自动的] 创建一个StringBuilder对象2.系统会 [自动的] 调用该对象的 append方法,完成字符串拼接3.系统会 [自动的] 调用该对象的 toString方法,完成类型转换 */
⚡面试题4⚡
public static void method4(){ String a="abc"; String b="a"+"b"+"c"; System.out.println(a==b); //true }
/* 原因: 因为Java有常量优化机制: 在javac(编译)的时候,就会将 "a" ,"b" ,"c"拼接为"abc" 所以在字节码文件中变成了 String a="abc"; String b="abc"; */
⚡面试题5⚡
public static void method5(){ /* 问创建了多少个字符串对象? 答: 3个 //一个是常量池里面的abc,两个是堆内存的abc(一个是a,一个是b) */ String a=new String("abc"); String b=new String("abc"); System.out.println(a==b); //false}
/* 1.第一步: a因为new关键字在堆内存开辟空间产生地址值如0x0011,然后因为有 "",所以去常量池创建了字符串abc, //常量池里面的abc对象然后把常量池里面的abc,拿这个副本给a,所以地址值0x0011存储了一个abc //堆内存的abc对象 2.第二步: b因为new关键字在堆内存开辟空间产生地址值如0x0022,然后因为有 "",所以去常量池准备创建abc, 但是发现常量池里面已经有了,所以直接拿副本给String b,所以地址值0x0022存储一个abc //堆内存的abc对象 */
作者:KJ.JK
文章对你有所帮助的话,欢迎给个赞或者 star,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习