这道关于String的面试题据说80%的人会答错!

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 这道关于String的面试题据说80%的人会答错!

这道关于String的面试题据说80%的人会答错!

很多人都会答错的一道关于String的题目,究竟有什么难度?

今天轻松点,我们一起来看一道关于String的面试题,准确说是改编的面试题!

小白: 庆哥,今天我们要学习什么知识啊?

庆哥: 今天我们就轻松一下,简单来看一道关于String的题目,毕竟等会我还要看沙海呢。

小白: 哈哈,没想到庆哥还追剧啊。

庆哥: 劳逸结合嘛,大脑总是需要休息的啊,看看电视剧休息一下还蛮好的,好了咱就不废话了,你知道在String中比较经典的一道面试题是什么吗?

小白: 这个好像是这道题吧

12
String s1 = new String("hello");    String s2 = new String("hello");

String s1 = new String(“hello”);
String s2 = new String(“hello”);

就是问以上代码创建了几个对象。

庆哥: 可以啊,我也觉得最经典的就是这道题了,考察的是关于String的重点知识点常量池和字符串优化,那么你知道这道题的答案吗?

小白: 这个是经典题了,答案是3个,因为这里的“hello”会在字符串常量池中创建一个,然后在堆中创建2个,所以这道题的答案一共是创建了三个对象。

庆哥: 你分析的非常对,不过我觉得更加严谨的一点说法是应该判断在字符串常量池中是否已经存在“hello”这个字符串,不过从这道题的本意来看,事先在字符串常量池中是不存在这个“hello”这个字符串的,所以你的说法是可以的,那么我们再来看看下面这道题

1234567891011
public class TestString {    public static void main(String[] args) {        String s1 = "Java";        String s2 = "从0到1";        String s3 = s1 + s2;        String s4 = "Java从0到1";         System.out.println(s3 == s4);      }}

public class TestString {
public static void main(String[] args) { String s1 = “Java”;
String s2 = “从0到1”;
String s3 = s1 + s2;
String s4 = “Java从0到1”;


    System.out.println(s3 == s4);
    

}

}

你说上面的代码执行一共创建了一个对象?

小白: 。。。这段代码我怎么看着这么别扭啊,让我想一哈!我觉得是4个对象!

庆哥: 为什么是4个呢?

小白: 首先我们直观看到的s1和s2还有s4都会在字符串常量池中创建字符串对象,重点就是s3了,在编译阶段不能确定s3的值,那么只有能运行时才能确定s3的值是“Java从0到1”,而这个字符串对象因为不是在编译期确定下来的,因此不会被放到字符串常量池中,会被放到堆中,这就又一个对象,加上之前的三个,所以一共有四个对象!

庆哥: 感觉你分析的很对啊,咱们先不来说的分析是对还是错,我先问你一个问题,你知道字符串常量池存放在内存中的哪个区域吗?

小白: 堆?还是方法区?懵了。。。

庆哥: 哈哈,找到知识缺漏了吧,对于字符串常量池的位置,字符串常量池在jdk1.6及之前在方法区中,但是在jdk1.7及以后就放在了堆中,我们现在一般很少使用jdk1.6及之前的版本,因此现在讨论所说的字符串常量池除非特别说明jdk版本,否则默认是在堆中。

另外对于字符串常量池中存放的是字符串对象,比如String a = “abc”那么在字符串常量池中就存放着这个abc,而这个abc则是一个字符串对象。

小白: 这下算是记住了,那对于这道题所需要的知识点是不是就是

  • 编译阶段确定的字符串才会被放到字符串常量池中
  • 字符串常量池在堆中
  • 字符串常量池在堆中

     

    庆哥: 是的,那你再分析下这道题,看看还会是之前的答案吗?

    小白: 。。不行,我还是分析不好,庆哥帮忙分析一下吧!

    庆哥: 那好吧,我就来说说吧!

    我们知道s1和s2还有s4都会在字符串常量池中,这已经有三个对象了,关键的分析点在这行代码上

    1
    String s3 = s1 + s2;

    String s3 = s1 + s2;

    对于s3无法在编译阶段确定下来,所以无论最后的字符串是什么都不会存在字符串常量池中,那么存在哪呢?因为对象创建在堆中,而字符串常量池也在堆中,既然不在字符串常量池中那就是在字符串常量池之外的堆中了,而s3最终的字符串对象是“Java从0到1”,那么也就是说这个字符串在常量池之外的堆中,这是一个对象了,加上之前的三个,这里一共四个了,但是我们还要分析这个s3是怎么来的,是通过s1和s2相加得到的,因为这个s3最终是在常量池之外的堆中形成的,而s1和s2都是在常量池中,因此会将s1和s2拷贝一份到字符串常量池之外的堆中来形成s3,我们看下面的一张图来加深理解

    这道关于String的面试题据说80%的人会答错!

    现在你说一共创建了几个对象?

    小白: 我去,原来还会复制啊,这样的话要再加上两个对象,那一共就是创建6个对象了!

    庆哥: 是的,其实一共创建了6个对象!那你知道这道题的输出结果吗?

    小白: 都分析的那么明白了,肯定知道啊,结果必须是false!

    庆哥: 哈哈,对了,那今天就到这啦!

    小白: 好,我赶紧做个笔记去!

    声明:此篇文章结论是在自己自学的前提下,参考一些资料和网上的文章得出的,还请高手给出意见,有不对的地方,烦请指出!不胜感激!

    这道关于String的面试题据说80%的人会答错!

     

    转发,分享,点赞,都是爱啊!

    本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> 这道关于String的面试题据说80%的人会答错!


     上一篇
    优雅的Java工具库Lombok 优雅的Java工具库Lombok
    最近在公司的项目中看到了对于Lombok的应用,通过@Data注解标注POJO,省略了大量的getter/setter代码,原先冗长的POJO在瘦身之后直接变得干净、清爽,程序员再也不需要去关注那些长长的方法,只需要集中注意力于
    下一篇 
    String类可以被继承吗?我们来聊聊final关键字! String类可以被继承吗?我们来聊聊final关键字!
    String类可以被继承吗?我们来聊聊final关键字! String在java基础知识中绝对是个重点知识,关于String的一些问题也是非常的多,而且牵涉到内存等高级知识,在面试中也是经常被考察的一个点,那么我们今天就来一起