jdk1.8中String的intern方法简单介绍

编程

jdk1.8中String的intern方法简单介绍

先来看三段代码:

String s1 = new String("abc");

s1.intern();

String s2 = "abc";

//s1 == s2 ? false

System.out.println(String.format("s1 == s2 ? %s", s1 == s2));

复制代码

String s3 = new String("def") + new String("");

s3.intern();

String s4 = "def";

//s3 == s4 ? false

System.out.println(String.format("s3 == s4 ? %s", s3 == s4));

复制代码

String s5 = new String("hi") + new String("j");

s5.intern();

String s6 = "hij";

//s5 == s6 ? true

System.out.println(String.format("s5 == s6 ? %s", s5 == s6));

复制代码

运行结果是

s1 == s2 ? false

s3 == s4 ? false

s5 == s6 ? true

复制代码

惊不惊喜,意不意外? 按道理应该都是true或者都是false对不对?

好下面来简单讲解一下:

首先贴一段jdk源码的注释,记住永远以源码以及源码注释作为最重要的参考, 其他的博客包括这篇都包含了作者的强烈的主观意识在里面可能会误导你。

/**

* Returns a canonical representation for the string object.

* <p>

* A pool of strings, initially empty, is maintained privately by the

* class {@code String}.

* <p>

* When the intern method is invoked, if the pool already contains a

* string equal to this {@code String} object as determined by

* the {@link #equals(Object)} method, then the string from the pool is

* returned. Otherwise, this {@code String} object is added to the

* pool and a reference to this {@code String} object is returned.

* <p>

* It follows that for any two strings {@code s} and {@code t},

* {@code s.intern() == t.intern()} is {@code true}

* if and only if {@code s.equals(t)} is {@code true}.

* <p>

* All literal strings and string-valued constant expressions are

* interned. String literals are defined in section 3.10.5 of the

* <cite>The Java&trade; Language Specification</cite>.

*

* @return a string that has the same contents as this string, but is

* guaranteed to be from a pool of unique strings.

*/

publicnative String intern();

复制代码

我英文不是很好,随便翻一下。 大意是说如果调用该方法,如果常量池中包含了一个和当前对象相等的字符串则返回常量池中的字符串, 否则把改字符串放到常量池中,并返回字符串的引用.

下面来简单看下第一段代码: 我们把

String s1 = new String("abc");

复制代码

拆成两部分

//此时常量池中没有abc,将abc放到常量池中

String s = "abc";

//对象s引用地址的hashCode

long sRefHashCode = System.identityHashCode(s);

System.out.println(String.format("s identityHashCode :[%s]", sRefHashCode));

String s1 = new String(s);

//对象s1引用地址的hashCode

long s1RefHashCode = System.identityHashCode(s1);

System.out.println(String.format("s1 identityHashCode :[%s]", s1RefHashCode));

//此时常量池中有abc,返回常量池中abc即对象s

String s1Intern = s1.intern();

long s1InternRefHashCode = System.identityHashCode(s1Intern);

System.out.println(String.format("s1Intern identityHashCode :[%s]", s1InternRefHashCode));

//此时常量池中有abc,返回abc,即对象s

String s2 = "abc";

//对象s2引用地址的hashCode

long s2RefHashCode = System.identityHashCode(s2);

System.out.println(String.format("s2 identityHashCode :[%s]", s2RefHashCode));

//false

System.out.println(String.format("s1RefHashCode == s1InternRefHashCode ? %s", s1RefHashCode == s1InternRefHashCode));

//false

System.out.println(String.format("s1RefHashCode == s2RefHashCode ? %s", s1RefHashCode == s2RefHashCode));

//true

System.out.println(String.format("s1InternRefHashCode == s2RefHashCode ? %s", s1InternRefHashCode == s2RefHashCode));

//false

System.out.println(String.format("s1 == s1Intern ? %s", s1 == s1Intern));

//false

System.out.println(String.format("s1 == s2 ? %s", s1 == s2));

//true

System.out.println(String.format("s1Intern == s2 ? %s", s1Intern == s2));

复制代码

把这段代码执行一遍,会发现
由于在创建s1之前,常量池中已经有abc了,
所以执行s1.intern()时直接返回了常量池中的abc,
s2也是从常量池中获取的,而s1则是重新创建的对象
所以
s1 == s1.intern() false
s1 == s2 false
s1.intern() == s2 true

第二段代码其实和第一段类似就不解释了

直接看第三段吧

String s1 = new String("hi") + new String("j");

long s1RefHashCode = System.identityHashCode(s1);

System.out.println(String.format("s1 identityHashCode :[%s]", s1RefHashCode));

//此时常量池中有没有hij,将s1放入到常量池并返回s1的引用

String s1Intern = s1.intern();

long s1InternRefHashCode = System.identityHashCode(s1Intern);

System.out.println(String.format("s1Intern identityHashCode :[%s]", s1InternRefHashCode));

//此时常量池中有hij,返回hij,即对象s1

String s2 = "hij";

long s2RefHashCode = System.identityHashCode(s2);

System.out.println(String.format("s2 identityHashCode :[%s]", s2RefHashCode));

//true

System.out.println(String.format("s1RefHashCode == s1InternRefHashCode ? %s", s1RefHashCode == s1InternRefHashCode));

//true

System.out.println(String.format("s1RefHashCode == s2RefHashCode ? %s", s1RefHashCode == s2RefHashCode));

//true

System.out.println(String.format("s1InternRefHashCode == s2RefHashCode ? %s", s1InternRefHashCode == s2RefHashCode));

//true

System.out.println(String.format("s1 == s1Intern ? %s", s1 == s1Intern));

//true

System.out.println(String.format("s1 == s2 ? %s", s1 == s2));

//true

System.out.println(String.format("s1Intern == s2 ? %s", s1Intern == s2));

复制代码

把这段代码执行一遍,会发现
由于在创建s1之前,常量池中没有hij,
所以执行s1.intern()时会将s1放入到常量池中,并返回s1的引用,
s2也是从常量池中获取的, 所以
s1 == s1.intern() true s1 == s2 true
s1.intern() == s2 true


 

以上是 jdk1.8中String的intern方法简单介绍 的全部内容, 来源链接: utcz.com/z/514835.html

回到顶部