Skip to content

面试速答(先看这里)

**一句话结论:**因为"ab"和"a"、"b"都是由字面量(""包裹的内容)组成的字符串,在编译之后,会把用"+"拼接的字面量直接合在一起。

60秒标准回答:

在Java中,对于字符串使用==比较的是字符串对象的引用地址是否相同

因为"ab"和"a"、"b"都是由字面量(""包裹的内容)组成的字符串,在编译之后,会把用"+"拼接的字面量直接合在一起。因此他们的最终都是"ab",而字面值最终在字符串池只有一份,所以a == b的结果为true,因为它们指向的是同一个字符串对象

在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(notation)。几乎所有计算机编程语言都具有对基本值的字面量表示,诸如:整数、浮点数以及字符串;而有很多也对布尔类型和字符类型的值也支持字面量表示;还有一些甚至对枚举类型的元素以及像数组、记录和对象等复合类型的值也支持字面量表示法

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**在Java中,对于字符串使用==比较的是字符串对象的引用地址是否相同。
  • **要点2:**在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(notation)。
  • **要点3:**以上是关于计算机科学中关于字面量的解释,并不是很容易理解。
  • **要点4:**JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。
  • **要点5:**了解Class文件结构或者做过Java代码的 反编译 的朋友可能都知道,在java代码被javac编译之后,文件结构中是包含一部分Constant pool的。

**记忆锚点:**Class → JVM → Java → 文件结构 → 字面量 → 的是同一个字符串对象

关键取舍:

  • JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。

易错提醒:

  • 以上是关于计算机科学中关于字面量的解释,并不是很容易理解。

追问准备:

  • 围绕「Class」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「JVM」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「Java」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

在Java中,对于字符串使用==比较的是字符串对象的引用地址是否相同。

因为"ab"和"a"、"b"都是由字面量(""包裹的内容)组成的字符串,在编译之后,会把用"+"拼接的字面量直接合在一起。因此他们的最终都是"ab",而字面值最终在字符串池只有一份,所以a == b的结果为true,因为它们指向的是同一个字符串对象。

📄 ✅String、StringBuilder和StringBuffer的区别?

扩展知识 ​

字面量 ​

在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(notation)。几乎所有计算机编程语言都具有对基本值的字面量表示,诸如:整数、浮点数以及字符串;而有很多也对布尔类型和字符类型的值也支持字面量表示;还有一些甚至对枚举类型的元素以及像数组、记录和对象等复合类型的值也支持字面量表示法。

以上是关于计算机科学中关于字面量的解释,并不是很容易理解。说简单点,字面量就是指由字母、数字等构成的字符串或者数值。

字面量只可以右值出现,所谓右值是指等号右边的值,如:int a=123这里的a为左值,123为右值。在这个例子中123就是字面量。

c
int a = 123;
String s = "hollis";

上面的代码事例中,123和hollis都是字面量。

JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。为了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串常量池。

在JVM中,有一块区域是运行时常量池,主要用来存储编译期生成的各种字面量和符号引用。

📄 ✅运行时常量池和字符串常量池的关系是什么?

打开文档:✅运行时常量池和字符串常量池的关系是什么?

了解Class文件结构或者做过Java代码的反编译的朋友可能都知道,在java代码被javac编译之后,文件结构中是包含一部分Constant pool的。比如以下代码:

c
public static void main(String[] args) {
    String s = "Hollis";
}

经过编译后,常量池内容如下:

c
 Constant pool:
   #1 = Methodref          #4.#20         // java/lang/Object."<init>":()V
   #2 = String             #21            // Hollis
   #3 = Class              #22            // StringDemo
   #4 = Class              #23            // java/lang/Object
   ...
   #16 = Utf8               s
   ..
   #21 = Utf8               Hollis
   #22 = Utf8               StringDemo
   #23 = Utf8               java/lang/Object

上面的Class文件中的常量池中,比较重要的几个内容:

c
   #16 = Utf8               s
   #21 = Utf8               Hollis
   #22 = Utf8               StringDemo

上面几个常量中,s就是前面提到的符号引用,而Hollis就是前面提到的字面量。

而Class文件中的常量池部分的内容,会在运行期被运行时常量池加载进去。