java基础-string
例子一
@Test
public void stringTest() {
String a = "hello" + " world";
String b = "hello world";
//结果为true
System.out.println(a==b);
}
变量a和变量b指向的内存地址是一样的
查看 编译字节码:
public stringTest()V
@Lorg/junit/jupiter/api/Test;()
L0
LINENUMBER 21 L0
LDC "hello world"
ASTORE 1
L1
LINENUMBER 22 L1
LDC "hello world"
ASTORE 2
L2
LINENUMBER 23 L2
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ALOAD 1
ALOAD 2
IF_ACMPNE L3
ICONST_1
GOTO L4
L3
FRAME FULL [com/shgjdhytb/java/InternTest java/lang/String java/lang/String] [java/io/PrintStream]
ICONST_0
L4
FRAME FULL [com/shgjdhytb/java/InternTest java/lang/String java/lang/String] [java/io/PrintStream I]
INVOKEVIRTUAL java/io/PrintStream.println (Z)V
L5
LINENUMBER 24 L5
RETURN
L6
LOCALVARIABLE this Lcom/shgjdhytb/java/InternTest; L0 L6 0
LOCALVARIABLE a Ljava/lang/String; L1 L6 1
LOCALVARIABLE b Ljava/lang/String; L2 L6 2
MAXSTACK = 3
MAXLOCALS = 3
例子二
@Test
public void stringTest() {
String c = "hello";
String a = c + " world";
String b = "hello world";
//结果为false
System.out.println(a == b);
}
变量a和变量b指向的内存地址是不一样的
查看 编译字节码:
public stringTest()V
@Lorg/junit/jupiter/api/Test;()
L0
LINENUMBER 29 L0
LDC "hello"
ASTORE 1
L1
LINENUMBER 30 L1
NEW java/lang/StringBuilder
DUP //注意这里!!,声明变量a
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
LDC " world"
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
ASTORE 2
L2
LINENUMBER 31 L2
LDC "hello world"
ASTORE 3
L3
LINENUMBER 32 L3
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ALOAD 2
ALOAD 3
IF_ACMPNE L4
ICONST_1
GOTO L5
L4
FRAME FULL [com/shgjdhytb/java/InternTest java/lang/String java/lang/String java/lang/String] [java/io/PrintStream]
ICONST_0
L5
FRAME FULL [com/shgjdhytb/java/InternTest java/lang/String java/lang/String java/lang/String] [java/io/PrintStream I]
INVOKEVIRTUAL java/io/PrintStream.println (Z)V
L6
LINENUMBER 33 L6
RETURN
L7
LOCALVARIABLE this Lcom/shgjdhytb/java/InternTest; L0 L7 0
LOCALVARIABLE c Ljava/lang/String; L1 L7 1
LOCALVARIABLE a Ljava/lang/String; L2 L7 2
LOCALVARIABLE b Ljava/lang/String; L3 L7 3
MAXSTACK = 3
MAXLOCALS = 4
可以发现,当声明变量a时,是通过创建StringBuilder对象方式拼接字符串,然后调用StringBuilder的toString方法
查看 StringBuilder 的 toString 方法 :
//jdk13
@Override
@HotSpotIntrinsicCandidate
public String toString() {
// Create a copy, don't share the array
return isLatin1() ? StringLatin1.newString(value, 0, count)
: StringUTF16.newString(value, 0, count);
}
//jdk7
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
意思是会创建全新的String对象,所以返回的不是常量池的"hello world"的地址,固变量a和变量b是不相等的