时间: 2021年2月25日星期四 多云
前言
面试是类似演讲演说的过程,网上的资料都是文字的,没法让面试者直观的体验到面试过程,本人已经将相关内容制作成音频节目,有兴趣的朋友可以去喜马拉雅搜索《2020年Java面试208题》收听音频版节目。
《2020年Java面试208题》整理了208个Java程序员的面试题,主要是针对三年以内开发经验的JAVA程序员提出的问题。
题目
本期要说的是《2020年Java面试208题》的第7题,面试官提了这样一个问题: String a=”i”与 String a=new String(“i”)一样吗
知识点解析
这个题目看起来简单,但其中涉及到Java的字符串常量池概念,还有Java对象的堆内存管理的概念,要把题目解答好,得把字符串常量池和堆内存。
我这个答题是尽量模拟现场面试的方式,演示答题过程与讲课的过程是不同的,有些知识点一带而过,基础薄弱的可能就看不明白了,我在这里先把知识点解释一下。
知识点讲解的时候涉及到堆、栈、代码区、类构造为对象、类的构造方法、这些概念,我就不能都解释了,有不理解的自行百度,因为计算机知识都是环环相扣的,我不能从底层再讲一遍编译原理。
1 Java的字符串常量池的概念
首先我们复习一下啥是字符串常量,在Java代码里面,用双引号框住的那样的字符串,那就是字符串常量。与任何常量都一样,这些都是写死在代码中的,是设计时的,就是说在程序设计的时候就已经确定的东西。
Java在管理常量的方式 -- 不仅仅是字符串常量,所有的常量都是这样的 -- 是在代码区开辟了一块区域保存常量。
这里又涉及到一个概念:代码区,我就不多做扩展解释了,其实应该好理解,程序员写的代码,最后肯定得读到内存中嘛,这个区域就是代码区。
在内存中一个Java类有一个代码区,一个代码区有一个常量池,常量池里面保存字符串常量的地方就是字符串常量池。
那么好了,可以看到本题目里面,第一种方式和第二种方式都有一个 字符串常量 “i”,因此可以想到,两种方式都要在字符串常量池里面开辟空间。
2 new String 是类构造成对象的过程
我们知道String 是一个类,而对象是类的实例化,面向对象中需要操作的都是对象,我们都是把类new出来成一个对象。
这个过程就是根据String类的定义,在内存中申请空间,创建出对象。
这个过程是调用了类的构造方法。
3 new String创建的对象是保存在堆里面的
不仅仅是new String ,Java中所有的new操作,都会构造一个对象,构造出来的对象都是保存在堆里面的。
演示面试
知识点铺垫完了,现在就由我来演示一下面试:
你好,面试官。
1 a赋值为字符串常量”i” 和 a赋值为 new String(字符串常量”i”) 是不同的。
两种方式得到的a这个变量来说,值都是一样的,都是字符串”i”。
区别是 a赋值为字符串常量”i”,是将字符串对象保存到字符串常量池中,这种方式只创建了一个字符串对象;
而 a赋值为new String(字符串常量”i”)的方式,会先在字符串常量池创建一个字符串对象,然后在堆内存中创建一个字符串对象,也就是说,这种方式会创建两个字符串对象。
详细的说一下:
第1种方式:a被赋值字符串常量”i”,这时候是程序代码中就确定了,根据常量”i”创建了一个字符串对象,保存在字符串常量池中,然后a定义指向到字符串常量池中的地址。
可以看出这个方式,只创建了一个字符串对象。
第2种方式:a被赋值 new String(字符串常量”i”),则执行了三步:
1 作为参数 字符串常量”i” ,必然要生成一个字符串常量对象,保存到字符串常量池;
2 new String这个构造方法,构造出一个字符串对象,并将上一步的字符串常量对象作为参数,然后将这个字符串对象写入堆内存中。
3 a指向到堆内存中的字符串对象的地址。
可以看出这个方式,实际是创建了两个字符串对象。
=========================================================
好了,以上就是我的演示面试,不知道是否让你满意。
下期再见
本人技术有限,只是希望给程序员面试提供一点帮助,必有不足之处,希望业内人士积极批评指正,在留言区留言就是对我最大的鼓励。希望批评中肯一些,不要存在人身攻击,更不要波及到家人,善意中肯的批评我都能够虚心接受。 我们下期再见。