Java基础学习总结:String.intern方法

String 的 intern() 方法用来返回常量池中的某字符串,如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用。否则,在常量池中加入该对象,然后返回引用。

intern()方法判断这个常量是否存在于常量池:

如果存在,判断存在内容是引用还是常量,如果是引用,返回引用地址指向堆空间对象的引用,如果是常量,直接返回常量池中该常量的引用。
如果不存在,将当前对象的引用复制到常量池,并且返回的是当前对象的引用。

JKD1.8之后把常量池移到了堆内存,这里为了便于理解,依旧把堆内存和常量池区分开来进行描述。

一个常量:

String str_1 = "AAA";
//判断常量池中是否存在“AAA”,存在,直接返回“AAA”的引用。
String str_2 = str_1.intern();
System.out.println(str_1 == str_2);//true,str_1 和 str_2 均指向常量池中的该常量。

两个常量相加:

//两个字面量均在常量池中
String str_1 = "AAA";
String str_2 = "BBB";
//str_3 = AAABBB;但是,str_3由于是在运行时动态赋值的,所以str_3保存在堆中;
//反编译后,该语句实际上是:String str_6 = (new StringBuilder()).append(str_1).append(str_2).toString();
String str_3 = str_1+str_2;
//intern()判断常量池中不存在“AAABBB”常量,于是把堆中“AAABBB”的引用(即地址)
//保存在常量池中,并返回该对象的引用;
String str_4 = str_3.intern();
//此时,str_3直接引用堆中的“AAABBB”,而Str_4通过常量池中保存的“AAABBB”的引用,
// 也间接引用堆中的“AAABBB”,故,str_3和str_4引用相同,返回true.
System.out.println(str_3 == str_4);

 一个常量和两个常量相加:

//两个字面量均在常量池中
String str_1 = "AAA";
String str_2 = "BBB";
//str_3依旧在堆内存中
String str_3 = str_1+str_2;
String str_4 = "AAABBB";
//intern()判断常量池中已经存在“AAABBB”字面量,直接返回该常量;
String str_5 = str_3.intern();
//此时,str_3指向堆内存中的对象,而str_4指向常量池中的常量,所以返回false
System.out.println(str_5 == str_3);

另一种情况: 

//两个字面量均在常量池中
String str_1 = "AAA";
String str_2 = "BBB";
//str_3依旧在堆内存中
String str_3 = str_1+str_2;
//intern()判断常量池中不存在“AAABBB”,则把堆内存中的“AAABBB”对象的引用放进常量池中,并返回该对象的引用;
String str_4 = str_3.intern();
//此时,常量池中已经存在常量“AAABBB”的引用,如果在想向常量池中添加“AAABBB”常量,
//JVM默认不执行,而是把常量池中“AAABBB”的引用返回给str_5;
String str_5= "AAABBB";
System.out.println(str_4 == str_3 && str_5==str_3);

 特殊字符 “java” :

//两个字面量均在常量池中
String str_1 = "ja";
String str_2 = "va";
//str_3在堆内存中
String str_3 = str_1+str_2;
//正常情况下,调用intern()方法,会把堆中str_3所指对象的引用放进常量池,因为,我们并没有把“java”字面量放进常量池,
// 但是,“java”这个单词非常特殊,默认存在于常量池,所以,intern()方法返回的不是堆中str_3所指对象的地址,
//而是常量池中的“java”的引用,所以结果为false。
String str_5 = str_3.intern();
System.out.println(str_5 == str_3);

 两个字面量相加:

//常量池中仅有一个“helloworld”对象,并没有在常量池中创建“hello”和“world”对象,
//因为都是常量,所以被虚拟机优化了,编译时就实现了两个常量的相加。
String ss9 = "hello"+"world";

创建一个String 对象:

String str = new String("AAA");
//会在常量池和堆内存中创建两个对象,一个是“AAA”字面量,存放在常量池中,
//一个是String对象,存在堆内存中。

 

你可能感兴趣的:(Java基础学习总结)