字符串串联时Java字符串池如何工作? [英] How Java String pool works when String concatenation?

查看:129
本文介绍了字符串串联时Java字符串池如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当心:如果字符相等,我不会尝试进行比较.因为我知道如何使用String.equals()方法.这个问题是关于字符串引用的

当我开始学习String类及其不可变性等属性时,我正在为OCA考试学习.据我对 String pool 的了解或可能了解的是,当字符串创建Java时会将此对象存储在他们称为 String pool 的对象上,如果创建了具有相同值的新字符串,它将引用 String pool 上的字符串除非我们使用 new 关键字,否则这会创建一个新引用,即使两个字符串都包含相同的值.

I was studying for the OCA exam when I started to learn about the class String and it properties as immutability, etc. According to what I read or may understand about String pool is that when a string is created Java stores this object on what they call String pool and if a new string is created with the same value it is going to make reference to the string on the String pool except is the case we use the new keyword as this creates a new reference even both string contains the same value.

例如:

String a = "foo";
String b = "foo";
String c = new String("foo");
boolean ab = (a == b); // This return true
boolean ac = (a == c); // This return false

为清楚起见,这段代码在第一行中将创建String a = "foo"并将其存储在字符串池中,然后在第二行代码中将其创建String b和对"foo"的引用,因为它已经存在于 String pool 中.但是第3行将创建此字符串的新引用,无论该字符串是否已存在.这是一个有关正在发生的事情的图形示例:

To be clear what this code is making is on the first line of code it will create the String a = "foo" and store this on the String pool, and on the second line of code it will create the String b and reference to "foo" because this already exist on the String pool. But line 3 will create a new reference of this string no matter if this already exist. Here is a little graphic example about what is happening:

问题出现在以下代码行上.通过串联创建字符串时,java是否会使某些内容不同或简单==比较器具有其他行为?

The problem comes on the followings lines of code. When the string is created by concatenation does java make something different or simple == comparator have another behaviour ?

示例A:

String a = "hello" + " world!";
String b = "hello world!";
boolean compare = (a == b); // This return true

示例B:

a = "hello";
b = "hel" + "lo";
compare = (a == b); // This return true

示例C:

a = "Bye";
a += " bye!";
b = "Bye bye!";
compare = (a == b); // This return false

要观看代码运行,请执行以下操作:( http://ideone.com/fdk6KL )

To watch the code running: (http://ideone.com/fdk6KL)

发生了什么事?

编辑

  1. 示例B的修复错误:b = 'hel' + 'lo'

添加有关该问题的说明.这不是一个比较问题,因为我知道使用String.equals()的问题是在字符串池的引用上

Adding clarification about the problem. It's not a comparison problem cause I know the use of String.equals() the problem is on the reference on the String pool

推荐答案

当通过串联创建字符串时,java会执行某些操作吗? 不同还是简单的==比较器还有其他行为?"

"When the string is created by concatenation does java make something different or simple == comparator have another behaviour?"

不,它不会改变其行为,发生的是:

No it does not change its behavior, what happens is that:

当连接两个字符串文字"a" + "b"时,jvm将两个值连接起来,然后检查字符串池,然后它意识到该值已经存在于该池中,因此只需将此引用分配给String.现在更详细:

When concatenating two string literals "a" + "b" the jvm joins the two values and then check the string pool, then it realizes the value already exists in the pool so it just simply assign this reference to the String. now in more details:

看下面这个简单程序的编译字节码:

Look at the compiled bytecode below of this simple program:

public class Test  {    
    public static void main(String... args) {
        String a = "hello world!";
        String b = "hello" + " world!";
        boolean compare = (a == b);
    }
}

首先,JVM加载字符串"hello world!",然后将其推送到字符串池(在这种情况下),然后将其加载到堆栈(ldc =加载常数). [请参见图像中的第1点]

First the JVM loads the string "hello world! and then push it to string pool (in this case) and then loads it to the stack (ldc = Load constant) [see point 1 in Image]

然后将在池中创建的引用分配给本地变量(astore_1) [请参见图像中的第2点]

Then it assign the reference created in the pool to the local variable (astore_1) [see point 2 in Image]

请注意,在字符串池中为此文字创建的引用是#2 [请参见图片中的第3点]

Notice that the reference created in the string pool for this literal is #2 [See point 3 in Image]

下一个操作大致相同:将字符串连接起来,将其推送到运行时常量池(在这种情况下为字符串池),但是随后它意识到具有相同内容的文字已经存在,因此它使用此引用(# 2)并分配给本地变量(astore_2).

The next operation is about the same: in concatenates the string, push it to the runtime constant pool (string pool in this case), but then it realizes a literal with the same content already exists so it uses this reference (#2) and assign in to a local variable (astore_2).

因此,当您执行(a == b)时,它们为 true ,因为它们两个都引用了字符串池#2,即"hello world!".

Thus when you do (a == b) is true because both of them are referencing to the string pool #2 which is "hello world!".

您的示例C与众不同,因为您使用的是+ =运算符,该运算符在编译为字节码时使用StringBuilder连接字符串,因此将创建StringBuilder Object的新实例,从而指向其他引用. (字符串池与对象)

Your example C is kind of different tho, because you're using the += operator which when compiled to bytecode it uses StringBuilder to concatenate the strings, so this creates a new instance of StringBuilder Object thus pointing to a different reference. (string pool vs Object)

这篇关于字符串串联时Java字符串池如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆