java字符串常量池与常量池,java-字符串常量池(JDK 6)中的“ a”与“ new String(“ a”)” vs“ new String(“ a”).intern()”...

我曾经知道以下两个语句在运行时在常量池中创建字符串a:

String s = "a"

String s = new String("a")

在JVM上测试它们时,两种情况下的permgen大小都相同.

但是,以下代码段的行为与此不同:

String s2 = null;

for (int i = 0; i < 100; i++)

{

s2 = s2 + i;

}

使用.intern(),在每次迭代中增加permgen的大小:

String s2 = null;

for (int i = 0; i < 100; i++)

{

s2 = s2 + i;

s2.intern();

}

为什么可以观察到这种行为? s2.intern()是否将条目添加到池中?这与这些声明有何不同?

String s = "a"

String s = new String("a")

解决方法:

这里有一点解释:

>“ a”在内部缓冲池中创建字符串“ a”(如果尚不存在)

> new String(“ a”),因为参数为“ a”,所以在内部存储池中创建了字符串“ a”(如果尚不存在),并且在内部存储池之外创建了“ a”的副本

>接受任何字符串s s.intern()返回该字符串的内部副本(如果存在于内部缓冲池中).如果没有,则将该字符串添加到内部缓冲池并返回新副本.

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

string equal to this String object as determined by the equals(Object)

method, then the string from the pool is returned. Otherwise, this

String object is added to the pool and a reference to this String

object is returned.

注意:要创建一个String并将其不添加到内部缓冲池中,可以使用chars数组作为String构造函数的参数:

char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };

String helloString = new String(helloArray);

这是对jls的引用,其中解释了在字符串的内部存储池中存在字符串文字:

A string literal is a reference to an instance of class String (§4.3.1, §4.3.3).

Moreover, a string literal always refers to the same instance of class

String. This is because string literals – or, more generally, strings

that are the values of constant expressions (§15.28) – are “interned”

so as to share unique instances, using the method String.intern.

这里是对最后一条评论的逐步解释:

// Creates the string "123", add it to the intern pool and assign "123" to s

String s = "123";

// s.intern() returns the intern string of s. Because s is already the

// string "123" present in the intern pool s and s.intern() are the same

System.out.println(s == s.intern());// true

// "123" is already in intern pool. new String("123") create a new String

// that equals "123" but it is a different object

String s2 = new String("123");

// It prints false because s2 is equals to "123", but not the same object

// because a new String was created in the preciding row

System.out.println(s2 == s);// false

// It prints true because s2.intern() returns the string present in the

// intern pool that is equals to s2. That string exists and is "123"

System.out.println(s2.intern() == s); // true

附加说明:对于等于s2的每个字符串s,如果s == s2也返回false,则s.intern()== s2.intern().

// If s equals s2 but are not the same

if (s.equals(s2) && s != s2) {

// THe intern string of s and s2 are always the same

System.out.println(s.intern() == s2.intern()); // prints always true

}

标签:jvm,string,java

来源: https://codeday.me/bug/20191027/1945323.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值