String.intern()使用總結

First Blood

先看下面的代碼:java

String s = new String("1");
String s1 = s.intern();
System.out.println(s == s1);
複製代碼
打印結果爲:
false
複製代碼

對於new String("1"),會生成兩個對象,一個是String類型對象,它將存儲在Java Heap中,另外一個是字符串常量對象"1",它將存儲在字符串常量池中。 s.intern()方法首先會去字符串常量池中查找是否存在字符串常量對象"1",若是存在則返回該對象的地址,若是不存在則在字符串常量池中生成爲一個"1"字符串常量對象,並返回該對象的地址。 以下圖: bash

image.png
變量 s指向的是Stirng類型對象,變量 s1指向的是"1"字符串常量對象,因此 s == s1結果爲false。

Double kill

在上面的基礎上咱們再定義一個s2以下:微信

String s = new String("1");
String s1 = s.intern();
String s2 = "1";
System.out.println(s == s1);
System.out.println(s1 == s2); // true
複製代碼

s1 == s2爲true,表示變量s2是直接指向的字符串常量,以下圖: 學習

image.png

Triple kill

在上面的基礎上咱們再定義一個t以下:優化

String s = new String("1");
String t = new String("1");
String s1 = s.intern();
String s2 = "1";
System.out.println(s == s1);
System.out.println(s1 == s2);
System.out.println(s == t);   // false
System.out.println(s.intern() == t.intern());   // true
複製代碼

s == t爲false,這個很明顯,變量s和變量t指向的是不一樣的兩個String類型的對象。 s.intern() == t.intern()爲true,由於intern方法返回的是字符串常量池中的同一個"1"對象,因此爲true。spa

image.png

Ultra kill

在上面的基礎上咱們再定義一個x和s3以下:code

String s = new String("1");
String t = new String("1");
String x = new String("1") + new String("1");
String s1 = s.intern();
String s2 = "1";
String s3 = "11";
System.out.println(s == s1);
System.out.println(s1 == s2);
System.out.println(s == t);
System.out.println(s.intern() == t.intern());
System.out.println(x == s3);  // fasle
System.out.println(x.intern() == s3.intern());  // true
複製代碼

變量x爲兩個String類型的對象相加,由於x != s3,因此x確定不是指向的字符串常量,實際上x就是一個String類型的對象,調用x.intern()方法將返回"11"對應的字符串常量,因此x.intern() == s3.intern()爲true。cdn

Rampage

將上面的代碼簡化並添加幾個變量以下:對象

String x = new String("1") + new String("1");
String x1 = new String("1") + "1";
String x2 = "1" + "1";
String s3 = "11";

System.out.println(x == s3);  // false
System.out.println(x1 == s3);  // false
System.out.println(x2 == s3); // true
複製代碼

x == s3爲false表示x指向String類型對象,s3指向字符串常量; x1 == s3爲false表示x1指向String類型對象,s3指向字符串常量; x2 == s3爲true表示x2指向字符串常量,s3指向字符串常量;blog

因此咱們能夠看到new String("1") + "1"返回的String類型的對象。

總結

如今咱們知道intern方法就是將字符串保存到常量池中,在保存字符串到常量池的過程當中會先查看常量池中是否已經存在相等的字符串,若是存在則直接使用該字符串。 因此咱們在寫業務代碼的時候,應該儘可能使用字符串常量池中的字符串,好比使用String s = "1";比使用new String("1");更節省內存。咱們也可使用String s  = 一個String類型的對象.intern();方法來間接的使用字符串常量,這種作法一般用在你接收到一個String類型的對象而又想節省內存的狀況下,固然你徹底能夠String s  = 一個String類型的對象;可是這麼用可能會由於變量s的引用而影響String類型對象的垃圾回收。因此咱們可使用intern方法進行優化,可是須要注意的是intern能節省內存,可是會影響運行速度,由於該方法須要去常量池中查詢是否存在某字符串。

若是以爲這篇文章能讓你學到知識,可否幫忙轉發,將知識分享出去。 若是想第一時間學習更多的精彩的內容,請關注微信公衆號:1點25

相關文章
相關標籤/搜索