public class TestDemo { @Test public void test01() { // String str1 = new StringBuilder("hello").append("World").toString(); System.out.println(str1.intern()); System.out.println(str1 == str1.intern()); String str2 = new StringBuilder("ja").append("va").toString(); System.out.println(str2.intern()); System.out.println(str2 == str2.intern()); String str3 = new StringBuilder("hello").toString(); System.out.println(str3.intern()); System.out.println(str3 == str3.intern()); } }
helloWorld true java false hello false
public class GCTest { public static void main(String[] args) { String str1 = new StringBuilder("ja").append("va").toString(); String str2 = str1.intern(); System.out.println(str1==str2); System.out.println(System.identityHashCode(str1)); // 通过System提供的方法得到hash值,打印hash值相当于内存地址,hashCode方法不完全等于 System.out.println(System.identityHashCode(str2)); // 打印地址 String str3 = new StringBuilder("hello").append("world").toString(); String str4 = str3.intern(); System.out.println(str3==str4); System.out.println(System.identityHashCode(str3)); System.out.println(System.identityHashCode(str4)); } }
false // str1和str2不是同一个对象 460141958 // 堆空间创建的那个对象 ”java“ 1163157884 // 字符串常量池中的字符串对象 true // 说明str3和str4是同一个对象 1956725890 // 堆中创建的字符串对象 ”helloworld“ 1956725890 // 堆中创建的字符串对象 ”helloworld“
helloWorld true
public class com.example.demo.test.TestDemo minor version: 0 major version: 58 flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #47 // com/example/demo/test/TestDemo super_class: #2 // java/lang/Object interfaces: 0, fields: 0, methods: 2, attributes: 1 Constant pool: #1 = Methodref #2.#3 // java/lang/Object."<init>":()V #2 = Class #4 // java/lang/Object #3 = NameAndType #5:#6 // "<init>":()V #4 = Utf8 java/lang/Object #5 = Utf8 <init> #6 = Utf8 ()V #7 = Class #8 // java/lang/StringBuilder #8 = Utf8 java/lang/StringBuilder #9 = String #10 // 常量"hello"字符串 #10 = Utf8 hello #11 = Methodref #7.#12 // java/lang/StringBuilder."<init>":(Ljava/lang/String;)V #12 = NameAndType #5:#13 // "<init>":(Ljava/lang/String;)V #13 = Utf8 (Ljava/lang/String;)V #14 = String #15 // 常量"World"字符串 #15 = Utf8 World #16 = Methodref #7.#17 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #17 = NameAndType #18:#19 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #18 = Utf8 append #19 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #20 = Methodref #7.#21 // java/lang/StringBuilder.toString:()Ljava/lang/String; #21 = NameAndType #22:#23 // toString:()Ljava/lang/String; #22 = Utf8 toString #23 = Utf8 ()Ljava/lang/String; #24 = Fieldref #25.#26 // java/lang/System.out:Ljava/io/PrintStream; #25 = Class #27 // java/lang/System #26 = NameAndType #28:#29 // out:Ljava/io/PrintStream; #27 = Utf8 java/lang/System #28 = Utf8 out #29 = Utf8 Ljava/io/PrintStream; #30 = Methodref #31.#32 // java/lang/String.intern:()Ljava/lang/String; #31 = Class #33 // java/lang/String #32 = NameAndType #34:#23 // intern:()Ljava/lang/String; #33 = Utf8 java/lang/String #34 = Utf8 intern #35 = Methodref #36.#37 // java/io/PrintStream.println:(Ljava/lang/String;)V #36 = Class #38 // java/io/PrintStream #37 = NameAndType #39:#13 // println:(Ljava/lang/String;)V #38 = Utf8 java/io/PrintStream #39 = Utf8 println #40 = Methodref #36.#41 // java/io/PrintStream.println:(Z)V #41 = NameAndType #39:#42 // println:(Z)V #42 = Utf8 (Z)V #43 = String #44 // 常量"ja"字符串 #44 = Utf8 ja #45 = String #46 // 常量"va"字符串 #46 = Utf8 va #47 = Class #48 // com/example/demo/test/TestDemo #48 = Utf8 com/example/demo/test/TestDemo #49 = Utf8 Code #50 = Utf8 LineNumberTable #51 = Utf8 LocalVariableTable #52 = Utf8 this #53 = Utf8 Lcom/example/demo/test/TestDemo; #54 = Utf8 test01 #55 = Utf8 str1 #56 = Utf8 Ljava/lang/String; #57 = Utf8 str2 #58 = Utf8 str3 #59 = Utf8 StackMapTable #60 = Utf8 RuntimeVisibleAnnotations #61 = Utf8 Lorg/junit/Test; #62 = Utf8 SourceFile #63 = Utf8 TestDemo.java { public com.example.demo.test.TestDemo(); descriptor: ()V flags: (0x0001) ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 7: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/example/demo/test/TestDemo; public void test01(); descriptor: ()V flags: (0x0001) ACC_PUBLIC Code: stack=3, locals=4, args_size=1 0: new #7 // 创建 java/lang/StringBuilder 对象 3: dup 4: ldc #9 // 入栈常量池(#9)中的字符串常量hello 6: invokespecial #11 // 实例初始化将hello传入 9: ldc #14 // 入栈常量池(在#14)中的字符串常量World 11: invokevirtual #16 // StringBuilder.append方法调用传入World 14: invokevirtual #20 // 调用StringBuilder.toString方法 17: astore_1 // 将返回的值的地址引用存入到局部变量1 18: getstatic #24 // 获取打印流 21: aload_1 // 将局部变量1装载成引用类型,也就是"helloWorld" 22: invokevirtual #30 // "helloWorld"调用String.intern:()方法 25: invokevirtual #35 // 调用打印流,打印"helloWorld" 28: getstatic #24 // 获取打印流 31: aload_1 // 加载局部变量1 也就是"helloWorld" 32: aload_1 // 加载局部变量1 "helloWorld" 33: invokevirtual #30 // "helloWorld"调用intern方法 36: if_acmpne 43 // 如果条件满足就转执行43 的iconst_0也就是将0入栈 39: iconst_1 // 将int类型常量值1压入栈 40: goto 44 // 无条件转移到44 43: iconst_0 // 将0入栈 44: invokevirtual #40 // 调用方法传入也就是“ja"(对应常量池的#44) 47: new #7 // 创建StringBuilder对象 50: dup 51: ldc #43 // 加载字符串"ja" 53: invokespecial #11 // 实例化StringBuilder 56: ldc #45 // 加载字符串"va" 58: invokevirtual #16 // 调用append方法 61: invokevirtual #20 // 调用toString方法 64: astore_2 // 将toString的结果存入局部变量2中 65: getstatic #24 // 获取打印流 68: aload_2 // 加载局部变量2的值也就是加载"java" 69: invokevirtual #30 // 调用intern方法 72: invokevirtual #35 // 打印"java" 75: getstatic #24 // 获取打印流 78: aload_2 // 加载局部变量2"java" 79: aload_2 // 加载局部变量2"java" 80: invokevirtual #30 // 调用intern方法 83: if_acmpne 90 // 如果条件成立跳转到90也就是将0入栈 86: iconst_1 // 将常量值1入栈 87: goto 91 // 无条件跳转到91 90: iconst_0 // 将常量值0入栈 91: invokevirtual #40 // 打印 94: new #7 // class java/lang/StringBuilder 97: dup 98: ldc #9 // String hello 100: invokespecial #11 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 103: invokevirtual #20 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 106: astore_3 107: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 110: aload_3 111: invokevirtual #30 // Method java/lang/String.intern:()Ljava/lang/String; 114: invokevirtual #35 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 117: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 120: aload_3 121: aload_3 122: invokevirtual #30 // Method java/lang/String.intern:()Ljava/lang/String; 125: if_acmpne 132 128: iconst_1 129: goto 133 132: iconst_0 133: invokevirtual #40 // Method java/io/PrintStream.println:(Z)V 136: return LineNumberTable: line 13: 0 line 14: 18 line 15: 28 line 17: 47 line 18: 65 line 19: 75 line 21: 94 line 22: 107 line 23: 117 line 24: 136 LocalVariableTable: Start Length Slot Name Signature 0 137 0 this Lcom/example/demo/test/TestDemo; 18 119 1 str1 Ljava/lang/String; 65 72 2 str2 Ljava/lang/String; 107 30 3 str3 Ljava/lang/String; StackMapTable: number_of_entries = 6 frame_type = 255 /* full_frame */ offset_delta = 43 locals = [ class com/example/demo/test/TestDemo, class java/lang/String ] stack = [ class java/io/PrintStream ] frame_type = 255 /* full_frame */ offset_delta = 0 locals = [ class com/example/demo/test/TestDemo, class java/lang/String ] stack = [ class java/io/PrintStream, int ] frame_type = 255 /* full_frame */ offset_delta = 45 locals = [ class com/example/demo/test/TestDemo, class java/lang/String, class java/lang/String ] stack = [ class java/io/PrintStream ] frame_type = 255 /* full_frame */ offset_delta = 0 locals = [ class com/example/demo/test/TestDemo, class java/lang/String, class java/lang/String ] stack = [ class java/io/PrintStream, int ] frame_type = 255 /* full_frame */ offset_delta = 40 locals = [ class com/example/demo/test/TestDemo, class java/lang/String, class java/lang/String, class java/lang/String ] stack = [ class java/io/PrintStream ] frame_type = 255 /* full_frame */ offset_delta = 0 locals = [ class com/example/demo/test/TestDemo, class java/lang/String, class java/lang/String, class java/lang/String ] stack = [ class java/io/PrintStream, int ] RuntimeVisibleAnnotations: 0: #61() org.junit.Test } SourceFile: "TestDemo.java"
java false
hello false
END 十期推荐 【241期】面试官:你了解JVM中的ZGC垃圾收集器吗? 【242期】面试官:Spring AOP有哪些通知类型,它们的执行顺序是怎样的? 【243期】面试官:什么是前缀索引、为什么要用前缀使用、用在什么场景下? 【244期】万字 图解 Redis,面试不用愁了! 【245期】面试官:MySQL发生死锁有哪些原因,怎么避免? 【246期】面试官:说说你对 RabbitMQ 的理解以及使用它的场景 【247期】记一次Java面试中遇到的三个问题及感悟! 【248期】面试官:你能说几个Java8中Stream对列表去重的方法吗? 【249期】关于Java中的异常,面试可以问的都在这里了! 【250期】关于Mybatis知识点,面试可以问的都在这里了! ? ~