您现在的位置是:亿华云 > 数据库

一个关于Java字符串对象问题的详细解答

亿华云2025-10-04 00:38:34【数据库】3人已围观

简介今天下班的路上,看到有人问这样一个问题:我看到这个问题的第一眼也有点懵。但如果把问题换成以下代码,答案对于我来说还是非常清晰的。Stringstr="test"+"1"; 但是当一个字符

今天下班的个关路上,看到有人问这样一个问题:

我看到这个问题的符串第一眼也有点懵。

但如果把问题换成以下代码,对象的详答答案对于我来说还是问题非常清晰的。

String str = "test" + "1"; 

但是细解当一个字符串和一个整数相加时,会创建几个对象呢?个关

作为老司机,深知实践是符串检验真理的唯一标准,动手才是对象的详答硬道理。

代码清单如下:

public class Hello {    public static void main(String[] args) {      String str = "test" + 1;     System.out.println(str);   } } 

编译以上代码,问题执行,细解控制台输出没有任何异议。个关

要看到创建了几个对象,符串我们需要反编译 Hello.class 文件,对象的云服务器提供商详答得到 java 字节码指令。问题

看到 main 方法的细解字节码指令,一切已经真相大白。

其实,作为一个老司机,早就应该想到是这样的结果。

可是,面对这样一道面试题,竟然还是还是蒙圈了。

那我们来解释一下 main 方法的第一条字节码指令。

0: ldc        ldc 的意思是 LoaD Constant,即从常量池中加载一个常量并压入(push)到操作数栈(operand stack)。 #2 是常量池中索引,服务器租用表示常量池中的第2项。

关于 ldc 字节码指令的详细说明,请参考官方文档,连接地址为:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc。

常量池中的第2个常量到底是什么,我们还需要使用 javap 命令来获得。

C:\Users\Thinkpad\Desktop>javap -v Hello.class Classfile /C:/Users/Thinkpad/Desktop/Hello.class   Last modified 2021-8-12; size 415 bytes   MD5 checksum d350245a83d24798f2269149002970f5   Compiled from "Hello.java" public class Hello   minor version: 0   major version: 52   flags: ACC_PUBLIC, ACC_SUPER Constant pool:    #1 = Methodref          #6.#15         // java/lang/Object."<init>":()V    #2 = String             #16            // test1    #3 = Fieldref           #17.#18        // java/lang/System.out:Ljava/io/PrintStream;    #4 = Methodref          #19.#20        // java/io/PrintStream.println:(Ljava/lang/String;)V    #5 = Class              #21            // Hello    #6 = Class              #22            // java/lang/Object    #7 = Utf8               <init>    #8 = Utf8               ()V    #9 = Utf8               Code   #10 = Utf8               LineNumberTable   #11 = Utf8               main   #12 = Utf8               ([Ljava/lang/String;)V   #13 = Utf8               SourceFile   #14 = Utf8               Hello.java   #15 = NameAndType        #7:#8          // "<init>":()V   #16 = Utf8               test1   #17 = Class              #23            // java/lang/System   #18 = NameAndType        #24:#25        // out:Ljava/io/PrintStream;   #19 = Class              #26            // java/io/PrintStream   #20 = NameAndType        #27:#28        // println:(Ljava/lang/String;)V   #21 = Utf8               Hello   #22 = Utf8               java/lang/Object   #23 = Utf8               java/lang/System   #24 = Utf8               out   #25 = Utf8               Ljava/io/PrintStream;   #26 = Utf8               java/io/PrintStream   #27 = Utf8               println   #28 = Utf8               (Ljava/lang/String;)V 

我们看到常量池(Constant pool)的第二项是:test1。

也就是说,javac 在编译代码过程中知道:

字符串 "test" 是一个字面值常量 整数 1 是一个字面值常量

所以,编译器将两个常量在编译过程中,计算然后合并成一个字符串常量test1,并保存在常量池中。

所以在代码执行过程中,根本就没有创建任何对象。站群服务器

本文转载自微信公众号「Golang In Memory」

很赞哦!(1761)