字符串是不可变的。究竟是什么意思? [英] String is immutable. What exactly is the meaning?

查看:183
本文介绍了字符串是不可变的。究竟是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在不可变字符串上编写了以下代码。

I wrote the following code on immutable Strings.

public class ImmutableStrings {

    public static void main(String[] args) {
        testmethod();
    }

    private static void testmethod() {
        String a = "a";
        System.out.println("a 1-->" + a);
        a = "ty";
        System.out.println("a 2-->" + a);
    }
}

输出:

a 1-->a  
a 2-->ty

这里变量 a 的值已被更改(许多人说不可更改对象的内容无法更改)。但是, String 是不可变的,究竟是什么意思呢?你能否为我澄清这个话题?

Here the value of variable a has been changed (while many say that contents of the immutable objects cannot be changed). But what exactly does one mean by saying String is immutable? Could you please clarify this topic for me?

来源: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

推荐答案

在继续进行 immutability 的大惊小怪之前,让我们来看看 String 类及其功能在得出任何结论之前一点。

Before proceeding further with the fuss of immutability, let's just take a look into the String class and its functionality a little before coming to any conclusion.

这是字符串的工作方式:

String str = "knowledge";

像往常一样,这会创建一个包含知识的字符串并为其指定一个参考 str 。够简单吗?让我们执行更多功能:

This, as usual, creates a string containing "knowledge" and assigns it a reference str. Simple enough? Lets perform some more functions:

 String s = str;     // assigns a new reference to the same string "knowledge"

让我们看看下面的语句是如何工作的:

Lets see how the below statement works:

  str = str.concat(" base");

这会追加一个字符串base STR 。但是等等,这怎么可能,因为 String 对象是不可变的?令你惊讶的是,它是。

This appends a string " base" to str. But wait, how is this possible, since String objects are immutable? Well to your surprise, it is.

当执行上述语句时,VM取值 String str ,即知识并附加base,为我们提供值的知识基。现在,由于 String 是不可变的,因此VM无法将此值分配给 str ,因此它会创建一个新的 String object,给它一个值知识库,并给它一个引用 str

When the above statement is executed, the VM takes the value of String str, i.e. "knowledge" and appends " base", giving us the value "knowledge base". Now, since Strings are immutable, the VM can't assign this value to str, so it creates a new String object, gives it a value "knowledge base", and gives it a reference str.

这里需要注意的一点是,虽然 String 对象是不可变,它的引用变量不是。这就是为什么在上面的例子中引用了引用新形成的 String 对象的原因。

An important point to note here is that, while the String object is immutable, its reference variable is not. So that's why, in the above example, the reference was made to refer to a newly formed String object.

在上面的例子中,我们有两个 String 对象:我们用值<创建的第一个对象知识 s 指向,第二个知识库,由 str 指向。但是,从技术上讲,我们有三个 String 对象,第三个是<$ c中的文字base $ c> concat 声明。

At this point in the example above, we have two String objects: the first one we created with value "knowledge", pointed to by s, and the second one "knowledge base", pointed to by str. But, technically, we have three String objects, the third one being the literal "base" in the concat statement.

如果我们没有其他参考 s 知识怎么办?我们会丢失 String 。但是,它仍然存在,但由于没有引用而被视为丢失。
再看下面的另一个例子

What if we didn't have another reference s to "knowledge"? We would have lost that String. However, it still would have existed, but would be considered lost due to having no references. Look at one more example below

String s1 = "java";
s1.concat(" rules");
System.out.println("s1 refers to "+s1);  // Yes, s1 still refers to "java"

发生了什么:


  1. 第一行很简单:创建一个新的字符串 java并将 s1 引用到它。

  2. 接下来,VM创建另一个新字符串 java规则,但没有
    指的是它。因此,第二个 String 会立即丢失。我们无法达到
    吧。

  1. The first line is pretty straightforward: create a new String "java" and refer s1 to it.
  2. Next, the VM creates another new String "java rules", but nothing refers to it. So, the second String is instantly lost. We can't reach it.

参考变量 s1 仍指原始字符串 java

几乎每个方法都应用于 String 对象以便修改它,创建新的 String 对象。那么,这些 String 对象去哪里了?好吧,这些存在于内存中,任何编程语言的关键目标之一就是有效利用内存。

Almost every method, applied to a String object in order to modify it, creates new String object. So, where do these String objects go? Well, these exist in memory, and one of the key goals of any programming language is to make efficient use of memory.

随着应用程序的增长, String 文字占用大面积内存非常常见,这甚至会导致冗余。因此,为了提高Java的效率, JVM预留了一个特殊的内存区域,称为字符串常量池。

As applications grow, it's very common for String literals to occupy large area of memory, which can even cause redundancy. So, in order to make Java more efficient, the JVM sets aside a special area of memory called the "String constant pool".

当编译器看到时字符串 literal,它在池中查找 String 。如果找到匹配项,则对新文本的引用将定向到现有的 String ,并且没有新的 String 对象是创建。现有的 String 只有一个参考。这里要点 String 对象不可变:

When the compiler sees a String literal, it looks for the String in the pool. If a match is found, the reference to the new literal is directed to the existing String and no new String object is created. The existing String simply has one more reference. Here comes the point of making String objects immutable:

字符串常量池, String 对象可能有一个或多个引用。 如果多个引用指向相同的 String 而不知道它,那么如果其中一个引用修改为 String 价值。这就是为什么 String 对象是不可变的。

In the String constant pool, a String object is likely to have one or many references. If several references point to same String without even knowing it, it would be bad if one of the references modified that String value. That's why String objects are immutable.

嗯,现在你可以说,是什么如果有人覆盖 String class的功能?这就是 String 类的原因标记为 final ,以便没有人可以覆盖其方法的行为。

Well, now you could say, what if someone overrides the functionality of String class? That's the reason that the String class is marked final so that nobody can override the behavior of its methods.

这篇关于字符串是不可变的。究竟是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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