100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > java String的intern()方法

java String的intern()方法

时间:2020-05-19 02:24:23

相关推荐

java String的intern()方法

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

本文章所用jdk版本为jdk1.8

先看第一个例子

public class HelloWorld {public static void main(String[] args) {String s1 = new String("hello") + new String("world");s1.intern();String s2 = "helloworld";System.out.println(s1==s2);}}

输出为:true

再看第二个例子

public class HelloWorld {public static void main(String[] args) {String s1 = new String("hello") + new String("world");String s2 = "helloworld";s1.intern();System.out.println(s1==s2);}}

输出为:false

明明只有一行代码的位置发生了改变,为什么会输出截然不同的结果呢?

下面开始分析。

jdk1.7后的intern方法在调用后,存在两种情况。

一、在调用后发现StringTable中没有所对应的字符串。String s1 = new String("hello") + new String("world");这句代码会在堆中new一个String对象(其实并没有这么简单,后面讲)s1.intern();s1调用了intern方法,然后发现在StringTable中并没有所对应的字符串,那么jvm就会在StringTable中放入一个地址,这个地址指向s1所new的String对象。String s2 = "helloworld";jvm发现在StringTable中已经存在指向"helloworld"的地址了,就会把StringTable中的地址给s2。此时s1和s2都指向这个地址。所以是同一个对象。于是返回了true

二、在调用后发现StringTable中存在所对应的字符串。String s1 = new String("hello") + new String("world");这句代码会在堆中new一个String对象(其实并没有这么简单,后面讲)String s2 = "helloworld";jvm在StringTable中存储这一个"helloworld"。此时s1和s2是两个不同的对象。s1指向堆中,s2指向StringTable。s1.intern();jvm发现在StringTable中已经存在"helloworld"了,那么什么都不会做,仅仅是返回这一个字符串。所以结果为false

下面讲一下String s1 = new String("hello") + new String("world");

底层做了什么。

public class HelloWorld {public static void main(String[] args) {String s1 = new String("hello") + new String("world");}}

先运行一遍,类加载器加载后,在target中会存在HelloWorld.class

public class HelloWorld {public HelloWorld() {}public static void main(String[] args) {String s1 = new String("hello") + new String("world");}}

运行指令javap -v target/classes/aa/HelloWorld.class进行反编译。

反编译后的详细信息如下:

Classfile /C:/Users/top/Downloads/untitled5/target/classes/aa/HelloWorld.classLast modified 4月14日; size 677 bytesSHA-256 checksum bf071098fdd9e51e927c011bb021cab16ac1227bd18a6435441f30e30b400f70Compiled from "HelloWorld.java"public class aa.HelloWorldminor version: 0major version: 52flags: (0x0021) ACC_PUBLIC, ACC_SUPERthis_class: #10// aa/HelloWorldsuper_class: #11 // java/lang/Objectinterfaces: 0, fields: 0, methods: 2, attributes: 1Constant pool:#1 = Methodref#11.#27 // java/lang/Object."<init>":()V#2 = Class #28 // java/lang/StringBuilder#3 = Methodref#2.#27 // java/lang/StringBuilder."<init>":()V#4 = Class #29 // java/lang/String#5 = String #30 // hello#6 = Methodref#4.#31 // java/lang/String."<init>":(Ljava/lang/String;)V#7 = Methodref#2.#32 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;#8 = String #33 // world#9 = Methodref#2.#34 // java/lang/StringBuilder.toString:()Ljava/lang/String;#10 = Class #35 // aa/HelloWorld#11 = Class #36 // java/lang/Object#12 = Utf8<init>#13 = Utf8()V#14 = Utf8Code#15 = Utf8LineNumberTable#16 = Utf8LocalVariableTable#17 = Utf8this#18 = Utf8Laa/HelloWorld;#19 = Utf8main#20 = Utf8([Ljava/lang/String;)V#21 = Utf8args#22 = Utf8[Ljava/lang/String;#23 = Utf8s1#24 = Utf8Ljava/lang/String;#25 = Utf8SourceFile#26 = Utf8HelloWorld.java#27 = NameAndType #12:#13 // "<init>":()V#28 = Utf8java/lang/StringBuilder#29 = Utf8java/lang/String#30 = Utf8hello#31 = NameAndType #12:#37 // "<init>":(Ljava/lang/String;)V#32 = NameAndType #38:#39 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;#33 = Utf8world#34 = NameAndType #40:#41 // toString:()Ljava/lang/String;#35 = Utf8aa/HelloWorld#36 = Utf8java/lang/Object#37 = Utf8(Ljava/lang/String;)V#38 = Utf8append#39 = Utf8(Ljava/lang/String;)Ljava/lang/StringBuilder;#40 = Utf8toString#41 = Utf8()Ljava/lang/String;{public aa.HelloWorld();descriptor: ()Vflags: (0x0001) ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 3: 0LocalVariableTable:Start Length Slot Name Signature0 50 this Laa/HelloWorld;public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: (0x0009) ACC_PUBLIC, ACC_STATICCode:stack=4, locals=2, args_size=10: new #2 // class java/lang/StringBuilder3: dup4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V7: new #4 // class java/lang/String10: dup11: ldc #5 // String hello13: invokespecial #6 // Method java/lang/String."<init>":(Ljava/lang/String;)V16: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;19: new #4 // class java/lang/String22: dup23: ldc #8 // String world25: invokespecial #6 // Method java/lang/String."<init>":(Ljava/lang/String;)V28: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;31: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;34: astore_135: returnLineNumberTable:line 5: 0line 6: 35LocalVariableTable:Start Length Slot Name Signature0360 args [Ljava/lang/String;35 11 s1 Ljava/lang/String;}SourceFile: "HelloWorld.java"

可以看到,1、jvm先new了一个StringBuilder(非多线程安全),2、然后new了一个String,3、调用了StringBuilder的append方法,添加了这一个String对象。4、再次new一个String对象5、再次调用了StringBuilder的append方法,添加了这一个String对象。6、调用StringBuilder的toString方法,将StringBuilder转为String

结束。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。