本篇是1000期面试系列文章的第192期,持续更新中.....

回复“面试”获取优质面试资源!

这篇来看看关于 Java String类的 5 道面试题,这五道题,我自己在面试过程中亲身经历过几道题目,本篇就带你了解这些题的答案为什么是这样。

st1和st2是否相等?

public class Demo2_String { public static void main(String[] args) {String st1 = "abc";String st2 = "abc";System.out.println(st1 == st2);System.out.println(st1.equals(st2));}
}

输出结果:

  • 第一行:true

  • 第二行:true

分析

先看第一个打印语句,在Java中==这个符号是比较运算符,它可以基本数据类型和引用数据类型是否相等,如果是基本数据类型,==比较的是值是否相等,如果是引用数据类型,==比较的是两个对象的内存地址是否相等。

字符串不属于8中基本数据类型,字符串对象属于引用数据类型,在上面把“abc”同时赋值给了st1和st2两个字符串对象,指向的都是同一个地址,所以第一个打印语句中的==比较输出结果是 true 然后我们看第二个打印语句中的equals的比较,我们知道,equals是Object这个父类的方法,在String类中重写了这个equals方法。

在JDK API 1.6文档中找到String类下的equals方法,点击进去可以看到这么一句话“将此字符串与指定的对象比较。当且仅当该参数不为null,并且是与此对象表示相同字符序列的String 对象时,结果才为 true。” 注意这个相同字符序列,在后面介绍的比较两个数组,列表,字典是否相等,都是这个逻辑去写代码实现。

由于st1和st2的值都是“abc”,两者指向同一个对象,当前字符序列相同,所以第二行打印结果也为true。下面我们来画一个内存图来表示上面的代码,看起来更加有说服力。

内存过程大致如下:

1)运行先编译,然后当前类Demo2_String.class文件加载进入内存的方法区

2)第二步,main方法压入栈内存

3)常量池创建一个“abc”对象,产生一个内存地址

4)然后把“abc”内存地址赋值给main方法里的成员变量st1,这个时候st1根据内存地址,指向了常量池中的“abc”。

5)前面一篇提到,常量池有这个特点,如果发现已经存在,就不在创建重复的对象

6)运行到代码 Stringst2 =”abc”, 由于常量池存在“abc”,所以不会再创建,直接把“abc”内存地址赋值给了st2

7)最后st1和st2都指向了内存中同一个地址,所以两者是完全相同的。

到底创建了几个对象?

String st1 = new String(“abc”);

答案是:在内存中创建两个对象,一个在堆内存,一个在常量池,堆内存对象是常量池对象的一个拷贝副本。

分析

我们下面直接来一个内存图。

当我们看到了new这个关键字,就要想到,new出来的对象都是存储在堆内存。然后我们来解释堆中对象为什么是常量池的对象的拷贝副本。

“abc”属于字符串,字符串属于常量,所以应该在常量池中创建,所以第一个创建的对象就是在常量池里的“abc”。

第二个对象在堆内存为啥是一个拷贝的副本呢,这个就需要在JDK API 1.6找到String(String original)这个构造方法的注释:初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。所以,答案就出来了,两个对象。

st1和st2是否相等?

package string;
public class Demo2_String {public static void main(String[] args) {String st1 = new String("abc");String st2 = "abc";System.out.println(st1 == st2);System.out.println(st1.equals(st2));}
}

答案:false 和 true 由于有前面两道题目内存分析的经验和理论,所以,我能快速得出上面的答案。

==比较的st1和st2对象的内存地址,由于st1指向的是堆内存的地址,st2看到“abc”已经在常量池存在,就不会再新建,所以st2指向了常量池的内存地址,所以==判断结果输出false,两者不相等。

第二个equals比较,比较是两个字符串序列是否相等,由于就一个“abc”,所以完全相等。

内存图如下

st1和st2是否相等?

public class Demo2_String { public static void main(String[] args) {String st1 = "a" + "b" + "c";String st2 = "abc";System.out.println(st1 == st2);System.out.println(st1.equals(st2));}
}

答案是:true 和 true 分析:“a”,”b”,”c”三个本来就是字符串常量,进行+符号拼接之后变成了“abc”,“abc”本身就是字符串常量(Java中有常量优化机制),所以常量池立马会创建一个“abc”的字符串常量对象,在进行st2=”abc”,这个时候,常量池存在“abc”,所以不再创建。所以,不管比较内存地址还是比较字符串序列,都相等。

判断一下st2和st3是否相等

public class Demo2_String {public static void main(String[] args) {String st1 = "ab";String st2 = "abc";String st3 = st1 + "c";System.out.println(st2 == st3);System.out.println(st2.equals(st3));}
}

答案:

  • false

  • true

分析

上面的答案第一个是false,第二个是true,第二个是true我们很好理解,因为比较一个是“abc”,另外一个是拼接得到的“abc”,所以equals比较,这个是输出true,我们很好理解。

那么第一个判断为什么是false,我们很疑惑。同样,下面我们用API的注释说明和内存图来解释这个为什么不相等。

首先,打开JDK API 1.6中String的介绍,找到下面图片这句话。

关键点就在红圈这句话,我们知道任何数据和字符串进行加号(+)运算,最终得到是一个拼接的新的字符串。+ 号操作到底做了什么?推荐看下。

上面注释说明了这个拼接的原理是由StringBuilder或者StringBuffer类和里面的append方法实现拼接,然后调用 toString() 把拼接的对象转换成字符串对象,最后把得到字符串对象的地址赋值给变量。结合这个理解,我们下面画一个内存图来分析。

大致内存过程

1)常量池创建“ab”对象,并赋值给st1,所以st1指向了“ab”

2)常量池创建“abc”对象,并赋值给st2,所以st2指向了“abc”

3)由于这里走的+的拼接方法,所以第三步是使用StringBuffer类的append方法,得到了“abc”,这个时候内存0x0011表示的是一个StringBuffer对象,注意不是String对象。

4)调用了Object的toString方法把StringBuffer对象装换成了String对象。

5)把String对象(0x0022)赋值给st3

所以,st3和st2进行==判断结果是不相等,因为两个对象内存地址不同。

总结

这篇的面试题,完全就是要求掌握JDK API中一些注解和原理,以及内存图分析,才能得到正确的结果,我承认是画内存图让我理解了答案为什么是这样。

好了,今天小蒋学就给大家分享这么多,希望对于正在准备面试的你有点滴帮助。

记得关注我噢!

参考:http://45dwz.com/JqUB9

精彩推荐

常见的SQL面试题:经典50例面试官:分布式事务解决方案(附代码)面试官:说说你对MySQL索引的理解这次面试稳了!看完50本面试总结后

5道String面试题,能全答对的人不到10%!(附答案)相关推荐

  1. python面试题_面试时全对这25道python面试题,成就了我月薪25K!附教程分享)

    之前面试的时候,面试官拿出一些python面试题对我说,只要全部正确直接给我20K,我一看题目笑了,居然全部都会,今天拿出来给大家分享一下~ 面试时全对这25道python面试题,成就了我月薪20K! ...

  2. 华南师范计算机复试试题,复试全接触——记我的复试(附教育史复试真题)(华南师范大学)...

    复试全接触--记我的复试(附教育史复试真题)(华南师范大学) 作者 songyl82 次阅读 2009-06-19 写在前面的话(关注真题的读者可略过此部分) 结束了自己的复试之旅,接下来面对开学前的 ...

  3. A里P7推荐68道Redis面试题,全是干货,20年面试必备

    Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库. Redis 可以存储键和五种不同类型的值之 ...

  4. 小米和腾讯的.NET笔面试题哪个更难?可自测附答案

    统计了下,当下正在招.NET的大厂有腾讯.京东.唯品会.阿里.百度.华为.小米.网易.特斯拉等.进大厂.拿高薪.享福利,应该是.NET程序员普世梦想了.金九银十将至,还不赶紧刷题准备?即使等金三银四, ...

  5. php sql update 字段a=字段b的信息_企业级PHP求职最全精品面试100问(附答案)

    本章中的面试问答几乎覆盖PHP面试中的方方面面,很久才整理出PHP面试中最为重要的100个面试题和答案,文章比较长,建议各位同学收藏阅读. 1,Http 和Https的区别 第一:http是超文本传输 ...

  6. 大厂面试官问你这些面试题你答的出吗?(附答案)

    1.问:你在测试中发现了一个bug,但是开发经理认为这不是一个bug,你应该怎样解决? 首先,将问题提交到缺陷管理库里面进行备案. 然后,要获取判断的依据和标准: 根据需求说明书.产品说明.设计文档等 ...

  7. html5引擎笔试题,最新!HTML5经典面试题型(附答案)

    HTML已更新至HTML5,那么HTML5的测试题您也应该知道,这篇文章可以作为您的参考. 1.doctype有什么作用呢?如何区分其混合模式和标准模式?所有这些都意味着什么? Doctype的作用是 ...

  8. 计算机绘图cad期末考试试题,2017大学cad期末考试练习题「附答案」

    [www.hywsbj.com--三会一课] 一.选择题 1.如果创建一个选择集,使选框所圈住及 所接触的图形选中,应采用 A.使用一个窗口选择 B.交叉 选择 C.在命令行输入CA D.按 shif ...

  9. 包头中考计算机考试试题2020,2020年内蒙古包头中考数学试卷附答案解析版.docx...

    在 在 此 卷 上 答 题 无 效 2020 年内蒙古包头市初中升学考试 数学 如图, ?ACD 是△ABC 的外角, CE∥AB .若?ACB ? 75? , ?ECD ? 50? ,则?A 的度数 ...

  10. 2023年PMP考生|考前必练全真模拟题分享,附答案解析

    "日日行,不怕千万里:常常做,不怕千万事."每日五题,备考无压力! 1.在敏捷项目管理中,产品负责人要从客户那里收集项目需求,并维护一个包含所有工作的有序列表,团队在每个冲刺前都要 ...

最新文章

  1. 一级域名和二级域名的区别是什么?作用怎样?
  2. python调用动态链接库windows_用win从python ctypes调用标准windows.dll的Segfault
  3. 【学术相关】TopPaper:AI 初学者经典论文列表
  4. pandas基本数据处理
  5. JavaWeb课程复习资料(六)——DAO与DAOImpl层封装
  6. Eclipse IDE中的Java 9 module-info文件
  7. mysql 操作表的例子,mysql中库和表的简单操作总结(附示例)
  8. GPU并行计算OpenCL(1)——helloworld
  9. .net excel导入mysql_.NET Core使用NPOI将Excel中的数据批量导入到MySQL - 追逐时光者 - 博客园...
  10. stringGrids 部分只读
  11. 凸优化有关的数值线性代数知识三:LU Cholesky和LDL因式分解
  12. matlab 读取同一文件中所有图像_matlab 批量读取文件夹内所有图片的几种方法
  13. 关于TCP/IP协议
  14. 2014年11月合肥黄山宏村之旅
  15. Python-Locust接口压力测试
  16. 西瓜书习题4.3 决策树
  17. 微信内置浏览器无法使用input图片上传和lrz.bundle.js图片压缩插件
  18. 如何正确修改标题,如何修改标题不会被降权?
  19. CentOS 使用 yum 源安装 PHP 各版本、及 PHP 各扩展总结
  20. java错误: xxx不是抽象的, 并且未覆盖xxx中的抽象方法

热门文章

  1. js实现数字金额转换大写及数字加千分符
  2. c语言自定义函数返回值的作用,C语言自定义函数
  3. Linux怎么恢复已删除的文件,Linux中使用extundelete恢复已删除的文件
  4. Word操作之图表目录自动生成
  5. 数字IC设计verilog编写——6脉冲同步器
  6. Windows 7各版本的主要功能区别是什么 有何不同
  7. 人脸识别+AI技术如何实现智慧工地履约考勤?
  8. ok6410linux usb驱动,linux OK6410 LED驱动
  9. mysql报错1194_ERROR 1194 (HY000): Table 't1' is marked as crashed and should be repaired
  10. java中创建一个类