Java 中字符串字面量与字符串对象的区别

2025 年 1 月 6 日 | 阅读 5 分钟

Java.lang.String 或 String 类是 API 中一个值得注意的类。String 类具有许多独特的功能,这些功能对许多程序员来说并不显而易见,这使得它在 Java API 中独树一帜。理解 String 类是学习 Java 的前提。此外,还有关于 String 是否为 final 类或 equals 与 == 运算符的常见疑问。因此,本文还包括了 API 中的字符串字面量和字符串对象。

字符串字面量

在 Java 中,字符串字面量本质上是源代码字符集中的一系列字符,开发者使用它们来填充字符串对象或向用户显示文本。这些由双引号表示的字符可以包含字母、数字或符号的任意组合。

声明语法

简单来说,当您以这种方式声明字符串时,我们正在调用 String 的 intern() 方法。该技术利用内部字符串对象池。如果一个字符串值(例如“abc”)已经存在,则不会创建新的 String 对象。在这种情况下,str 将引用现有的字符串。

字符串对象

字符串对象允许您操作字符序列。它本质上封装了 JavaScript 的所有原始字符串数据类型,并包含几个方便的方法。JavaScript 的主要作用是自动将字符串从原始字符串转换为字符串对象。

声明语法

这是一个由字符串组成的示例。即使“abc”已在引用池中,JVM 也必须使用此技术创建一个新的字符串引用。因此,由于字符串对象在每次处理时都会创建一个新字符串,因此在比较字符串字面量和字符串对象之间的性能时,字符串对象的执行速度将始终慢于字符串字面量。

例如,以下两个表达式形成的 String 对象有什么区别?

这两个表达式之间存在细微差别,但它们都返回一个 String 对象。每当我们使用 new() 运算符创建 String 对象时,总是在堆内存中创建新对象。然而,当我们使用字符串字面量语法(例如“abc”)创建对象时,它可以从 String 池(Java 版本中已迁移到堆空间的 Perm gen 空间中字符串对象的缓存)返回现有对象。如果不存在,它将生成一个新的字符串对象并将其存储在字符串池中以供以后使用。

String Literal Vs String Object in Java

示例

此 Java 程序比较了使用字符串字面量与字符串对象的性能(时间)参数。在循环中初始化了两个字符串“Hello”和“World”;一个使用字符串字面量,另一个使用字符串对象。通过跟踪每个循环的开始和结束时间并计算差值,程序确定每个初始化过程需要多长时间。

最终,将打印出每种技术的总花费时间。它有助于我们展示使用字符串字面量(存储在字符串池中,如果已存在则重用)与直接创建新字符串对象在执行时间上的差异。

实施

文件名: DiffPerformanceStringLiteralObject.java

输出

The total time taken to execute for string literal = 0
The total time taken to execute for string object = 1

复杂度分析

上述代码的时间复杂度为 O(N),其中 N 表示迭代次数,空间复杂度为 O(1)。

字符串字面量与字符串对象的区别

字符串字面量字符串对象
创建字符串字面量时,使用双引号("")括起来。使用 String 构造函数和 new 关键字创建 String 对象。
当您创建字符串字面量时,Java 会在堆内存中指定的区域——字符串池中查找相同的字符串。当您使用 new String() 创建字符串对象时,Java 会在堆中分配 RAM 来存储字符串。
如果字符串已存在于字符串池中,Java 将重用该字符串并仅返回其引用。即使字符串已存在,使用 new String() 也会在堆中创建一个新对象,而不管字符串池。
如果字符串不存在于字符串池中,Java 将在池中创建一个新的字符串对象并返回其引用。字符串对象可以存储在通用堆内存中,而不是存储在字符串池中。
字符串字面量存储在堆内存中,由多个计算机组件共享的字符串池中。New String() 创建的字符串对象在通用堆中分配内存,每个对象都有自己的内存空间。
由于内容相同的字符串字面量将具有相同的内存引用,因此 == 比较会将它们视为相等。由于使用 new String() 创建的内容相同的字符串对象使用不同的内存引用,因此除非使用 .equals() 函数进行特定比较,否则不能使用 == 运算符进行比较。
由于字符串驻留(在字符串池中重用已存在的字符串),字符串字面量通常更具性能和内存效率。即使字符串相同且已存在于字符串池中,使用 new String() 创建的字符串对象效率较低,因为它们不断在堆上分配新的内存空间。
示例: String str = "abc";示例: String str = new String("abc");