为什么 Java 和 .NET 中的字符串不能可变?

发布于 2024-07-05 08:22:40 字数 78 浏览 8 评论 0原文

为什么他们决定在 Java 和 .NET(以及其他一些语言)中使 String 不可变? 他们为什么不让它可变呢?

Why is it that they decided to make String immutable in Java and .NET (and some other languages)? Why didn't they make it mutable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

吝吻 2024-07-12 08:22:40

根据 Effective Java,第 4 章,第 73 页,第 2 版:

“这样做有很多充分的理由:不可变类更容易
设计、实现和使用比可变类更重要。 他们不太容易
错误并且更安全。

[...]

不可变对象很简单。不可变对象可以位于
正是一种状态,即它被创建的状态。 如果你确定
所有构造函数都建立类不变量,那么它是
保证这些不变量将永远保持正确,并且
您无需付出任何努力。

[...]

不可变对象本质上是线程安全的; 它们不需要同步。它们不会被多个线程破坏
同时访问它们。 这无疑是最简单的方法
来实现线程安全。 事实上,没有线程可以观察到任何
另一个线程对不可变对象的影响。 所以,
不可变对象可以自由共享

[...]

同一章的其他小点:

您不仅可以共享不可变对象,还可以共享它们的内部结构。

[...]

不可变对象可以为其他对象(无论是可变的还是不可变的)提供很好的构建块。

[...]

不可变类的唯一真正缺点是它们需要为每个不同的值提供一个单独的对象。

According to Effective Java, chapter 4, page 73, 2nd edition:

"There are many good reasons for this: Immutable classes are easier to
design, implement, and use than mutable classes. They are less prone
to error and are more secure.

[...]

"Immutable objects are simple. An immutable object can be in
exactly one state, the state in which it was created. If you make sure
that all constructors establish class invariants, then it is
guaranteed that these invariants will remain true for all time, with
no effort on your part.

[...]

Immutable objects are inherently thread-safe; they require no synchronization. They cannot be corrupted by multiple threads
accessing them concurrently. This is far and away the easiest approach
to achieving thread safety. In fact, no thread can ever observe any
effect of another thread on an immutable object. Therefore,
immutable objects can be shared freely

[...]

Other small points from the same chapter:

Not only can you share immutable objects, but you can share their internals.

[...]

Immutable objects make great building blocks for other objects, whether mutable or immutable.

[...]

The only real disadvantage of immutable classes is that they require a separate object for each distinct value.

落叶缤纷 2024-07-12 08:22:40

至少有两个原因。

第一 - 安全性 http://www.javafaq.nu/java-article1060 .html

String 制作的主要原因
不变就是安全。 看这个
示例:我们有一个文件打开方法
与登录检查。 我们传递一个字符串到
这个方法来处理认证
在通话之前这是必要的
将传递给操作系统。 如果字符串是
可变的,有可能以某种方式
之后修改其内容
操作系统获取之前的身份验证检查
来自程序的请求那么它是
可以请求任何文件。 因此,如果
您有权打开文本文件
用户目录,但随后动态
当你设法改变
您可以请求打开的文件名
“passwd”文件或任何其他文件。 然后一个
文件可以被修改,它将是
可以直接登录操作系统。

第二 - 内存效率 http: //hikrish.blogspot.com/2006/07/why-string-class-is-immutable.html

JVM内部维护“String
Pool”。实现记忆
效率,JVM会引用String
池中的对象。 它不会创建
新的 String 对象。 所以,每当
你创建一个新的字符串文字,JVM
将在池中检查是否
已经存在或不存在。 如果已经
存在于池中,只需给出
引用同一个对象或创建
池中的新对象。 这里将
许多参考文献都指向同一个
字符串对象,如果有人更改
值,它会影响所有
参考。 于是,sun决定这么做
不可变。

There are at least two reasons.

First - security http://www.javafaq.nu/java-article1060.html

The main reason why String made
immutable was security. Look at this
example: We have a file open method
with login check. We pass a String to
this method to process authentication
which is necessary before the call
will be passed to OS. If String was
mutable it was possible somehow to
modify its content after the
authentication check before OS gets
request from program then it is
possible to request any file. So if
you have a right to open text file in
user directory but then on the fly
when somehow you manage to change the
file name you can request to open
"passwd" file or any other. Then a
file can be modified and it will be
possible to login directly to OS.

Second - Memory efficiency http://hikrish.blogspot.com/2006/07/why-string-class-is-immutable.html

JVM internally maintains the "String
Pool". To achive the memory
efficiency, JVM will refer the String
object from pool. It will not create
the new String objects. So, whenever
you create a new string literal, JVM
will check in the pool whether it
already exists or not. If already
present in the pool, just give the
reference to the same object or create
the new object in the pool. There will
be many references point to the same
String objects, if someone changes the
value, it will affect all the
references. So, sun decided to make it
immutable.

等你爱我 2024-07-12 08:22:40

实际上,java中字符串不可变的原因与安全性没有太大关系。 两个主要原因如下:

Thead Safety:

字符串是使用极其广泛的对象类型。 因此或多或少保证可以在多线程环境中使用。 字符串是不可变的,以确保在线程之间共享字符串是安全的。 拥有不可变字符串可确保将字符串从线程 A 传递到另一个线程 B 时,线程 B 不会意外修改线程 A 的字符串。

这不仅有助于简化已经相当复杂的多线程编程任务,而且还有助于提高多线程应用程序的性能。 当可以从多个线程访问可变对象时,对可变对象的访问必须以某种方式同步,以确保一个线程在另一线程修改对象时不会尝试读取对象的值。 对于程序员来说,正确的同步很难正确完成,而且运行时的成本也很高。 不可变对象无法修改,因此不需要同步。

性能:

虽然已经提到了字符串驻留,但它仅代表 Java 程序内存效率的微小提升。 仅字符串文字被保留。 这意味着只有源代码中相同的字符串才会共享相同的字符串对象。 如果您的程序动态创建相同的字符串,它们将在不同的对象中表示。

更重要的是,不可变字符串允许它们共享内部数据。 对于许多字符串操作,这意味着不需要复制底层字符数组。 例如,假设您想获取 String 的前五个字符。 在 Java 中,您可以调用 myString.substring(0,5)。 在本例中,substring() 方法所做的只是创建一个新的 String 对象,该对象共享 myString 的底层 char[],但谁知道它从该 char[] 的索引 0 开始,到索引 5 结束。 以图形形式表示,您最终会得到以下结果:

 |               myString                  |
 v                                         v
"The quick brown fox jumps over the lazy dog"   <-- shared char[]
 ^   ^
 |   |  myString.substring(0,5)

这使得此类操作极其便宜,并且 O(1),因为该操作既不依赖于原始字符串的长度,也不依赖于我们所要的子字符串的长度。需要提取。 此行为还具有一些内存优势,因为许多字符串可以共享其底层 char[]。

Actually, the reasons string are immutable in java doesn't have much to do with security. The two main reasons are the following:

Thead Safety:

Strings are extremely widely used type of object. It is therefore more or less guaranteed to be used in a multi-threaded environment. Strings are immutable to make sure that it is safe to share strings among threads. Having an immutable strings ensures that when passing strings from thread A to another thread B, thread B cannot unexpectedly modify thread A's string.

Not only does this help simplify the already pretty complicated task of multi-threaded programming, but it also helps with performance of multi-threaded applications. Access to mutable objects must somehow be synchronized when they can be accessed from multiple threads, to make sure that one thread doesn't attempt to read the value of your object while it is being modified by another thread. Proper synchronization is both hard to do correctly for the programmer, and expensive at runtime. Immutable objects cannot be modified and therefore do not need synchronization.

Performance:

While String interning has been mentioned, it only represents a small gain in memory efficiency for Java programs. Only string literals are interned. This means that only the strings which are the same in your source code will share the same String Object. If your program dynamically creates string that are the same, they will be represented in different objects.

More importantly, immutable strings allow them to share their internal data. For many string operations, this means that the underlying array of characters does not need to be copied. For example, say you want to take the five first characters of String. In Java, you would calls myString.substring(0,5). In this case, what the substring() method does is simply to create a new String object that shares myString's underlying char[] but who knows that it starts at index 0 and ends at index 5 of that char[]. To put this in graphical form, you would end up with the following:

 |               myString                  |
 v                                         v
"The quick brown fox jumps over the lazy dog"   <-- shared char[]
 ^   ^
 |   |  myString.substring(0,5)

This makes this kind of operations extremely cheap, and O(1) since the operation neither depends on the length of the original string, nor on the length of the substring we need to extract. This behavior also has some memory benefits, since many strings can share their underlying char[].

把昨日还给我 2024-07-12 08:22:40

线程安全和性能。 如果无法修改字符串,则可以安全且快速地在多个线程之间传递引用。 如果字符串是可变的,则您始终必须将字符串的所有字节复制到新实例,或提供同步。 典型的应用程序每次需要修改字符串时都会读取该字符串 100 次。 请参阅维基百科有关不变性的内容。

Thread safety and performance. If a string cannot be modified it is safe and quick to pass a reference around among multiple threads. If strings were mutable, you would always have to copy all of the bytes of the string to a new instance, or provide synchronization. A typical application will read a string 100 times for every time that string needs to be modified. See wikipedia on immutability.

々眼睛长脚气 2024-07-12 08:22:40

人们真的应该问:“为什么 X 应该是可变的?” 最好默认为不变性,因为 绒毛公主。 某些东西是可变的,这应该是一个例外。

不幸的是,当前大多数编程语言都默认为可变性,但希望将来的默认值更多地是不变性(请参阅下一个主流编程语言的愿望清单)。

One should really ask, "why should X be mutable?" It's better to default to immutability, because of the benefits already mentioned by Princess Fluff. It should be an exception that something is mutable.

Unfortunately most of the current programming languages default to mutability, but hopefully in the future the default is more on immutablity (see A Wish List for the Next Mainstream Programming Language).

夜还是长夜 2024-07-12 08:22:40

哇! 我不敢相信这里的错误信息。 String 的不可变性与安全性没有任何关系。 如果某人已经可以访问正在运行的应用程序中的对象(如果您试图防止有人“破解”您的应用程序中的 String ,则必须假设这一点),他们肯定会是很多其他可用于黑客攻击的机会。

String 的不变性正在解决线程问题,这是一个相当新颖的想法。 嗯...我有一个对象正在被两个不同的线程更改。 我该如何解决这个问题? 同步对象的访问? Naawww ...让我们根本不让任何人更改对象 - 这将解决我们所有混乱的并发问题! 事实上,让所有对象都是不可变的,然后我们就可以从 Java 语言中删除同步结构。

真正的原因(上面其他人指出)是内存优化。 在任何应用程序中重复使用相同的字符串文字都是很常见的。 事实上,这种情况非常常见,以至于几十年前,许多编译器都进行了仅存储 String 文字的单个实例的优化。 此优化的缺点是修改 String 文字的运行时代码会引入问题,因为它正在修改共享该实例的所有其他代码的实例。 例如,对于应用程序中某处的函数来说,将 String 文字 "dog" 更改为 "cat" 并不好。 printf("dog") 会导致 "cat" 被写入标准输出。 出于这个原因,需要有一种方法来防止代码试图更改String文字(即,使它们不可变)。 某些编译器(在操作系统的支持下)会通过将 String 文字放入特殊的只读内存段来实现此目的,如果尝试进行写入,则会导致内存错误。

在 Java 中,这称为实习。 这里的 Java 编译器只是遵循编译器几十年来完成的标准内存优化。 为了解决这些 String 文字在运行时被修改的相同问题,Java 只是使 String 类不可变(即,不给你任何允许你更改 String 内容)。 如果没有发生String 文字的驻留,String 就不必是不可变的。

Wow! I Can't believe the misinformation here. Strings being immutable have nothing with security. If someone already has access to the objects in a running application (which would have to be assumed if you are trying to guard against someone 'hacking' a String in your app), they would certainly be a plenty of other opportunities available for hacking.

It's a quite novel idea that the immutability of String is addressing threading issues. Hmmm ... I have an object that is being changed by two different threads. How do I resolve this? synchronize access to the object? Naawww ... let's not let anyone change the object at all -- that'll fix all of our messy concurrency issues! In fact, let's make all objects immutable, and then we can removed the synchonized contruct from the Java language.

The real reason (pointed out by others above) is memory optimization. It is quite common in any application for the same string literal to be used repeatedly. It is so common, in fact, that decades ago, many compilers made the optimization of storing only a single instance of a String literal. The drawback of this optimization is that runtime code that modifies a String literal introduces a problem because it is modifying the instance for all other code that shares it. For example, it would be not good for a function somewhere in an application to change the String literal "dog" to "cat". A printf("dog") would result in "cat" being written to stdout. For that reason, there needed to be a way of guarding against code that attempts to change String literals (i. e., make them immutable). Some compilers (with support from the OS) would accomplish this by placing String literal into a special readonly memory segment that would cause a memory fault if a write attempt was made.

In Java this is known as interning. The Java compiler here is just following an standard memory optimization done by compilers for decades. And to address the same issue of these String literals being modified at runtime, Java simply makes the String class immutable (i. e, gives you no setters that would allow you to change the String content). Strings would not have to be immutable if interning of String literals did not occur.

牵你的手,一向走下去 2024-07-12 08:22:40

对于大多数用途,“字符串”是(用作/视为/认为/假定为)有意义的原子单位就像数字

因此,询问为什么字符串的各个字符不可变就像询问为什么整数的各个位不可变一样。

你应该知道为什么。 考虑一下。

我不想这么说,但不幸的是,我们正在争论这个问题,因为我们的语言很糟糕,而且我们试图使用一个单词,字符串来描述一个复杂的,上下文相关的概念或对象类别。

我们使用“字符串”进行计算和比较,类似于我们使用数字进行计算和比较。 如果字符串(或整数)是可变的,我们就必须编写特殊的代码将它们的值锁定为不可变的本地形式,以便可靠地执行任何类型的计算。 因此,最好将字符串视为数字标识符,但它的长度不是 16、32 或 64 位,而是可能有数百位。

当有人说“字符串”时,我们都会想到不同的东西。 那些将其简单地视为一组角色、没有特定目的的人当然会感到震惊,因为有人刚刚决定他们不应该能够操纵这些角色。 但“string”类不仅仅是字符数组。 它是 STRING,而不是 char[]。 关于我们称为“字符串”的概念有一些基本假设,它通常可以被描述为有意义的、编码数据的原子单元,如数字。 当人们谈论“操作字符串”时,也许他们实际上是在谈论操作字符来构建字符串,而 StringBuilder 非常适合这样做。 稍微思考一下“字符串”这个词的真正含义。

考虑一下如果字符串是可变的会是什么样子。 如果在该函数使用时另一个线程有意或无意地修改了可变用户名字符串,则以下 API 函数可能会被欺骗而返回不同用户的信息:

string GetPersonalInfo( string username, string password )
{
    string stored_password = DBQuery.GetPasswordFor( username );
    if (password == stored_password)
    {
        //another thread modifies the mutable 'username' string
        return DBQuery.GetPersonalInfoFor( username );
    }
}

安全性不仅仅是“访问控制” ”,这也与“安全”和“保证正确性”有关。 如果一个方法不容易编写并且无法可靠地执行简单的计算或比较,那么调用它是不安全的,但对编程语言本身提出质疑是安全的。

For most purposes, a "string" is (used/treated as/thought of/assumed to be) a meaningful atomic unit, just like a number.

Asking why the individual characters of a string are not mutable is therefore like asking why the individual bits of an integer are not mutable.

You should know why. Just think about it.

I hate to say it, but unfortunately we're debating this because our language sucks, and we're trying to using a single word, string, to describe a complex, contextually situated concept or class of object.

We perform calculations and comparisons with "strings" similar to how we do with numbers. If strings (or integers) were mutable, we'd have to write special code to lock their values into immutable local forms in order to perform any kind of calculation reliably. Therefore, it is best to think of a string like a numeric identifier, but instead of being 16, 32, or 64 bits long, it could be hundreds of bits long.

When someone says "string", we all think of different things. Those who think of it simply as a set of characters, with no particular purpose in mind, will of course be appalled that someone just decided that they should not be able to manipulate those characters. But the "string" class isn't just an array of characters. It's a STRING, not a char[]. There are some basic assumptions about the concept we refer to as a "string", and it generally can be described as meaningful, atomic unit of coded data like a number. When people talk about "manipulating strings", perhaps they're really talking about manipulating characters to build strings, and a StringBuilder is great for that. Just think a bit about what the word "string" truly means.

Consider for a moment what it would be like if strings were mutable. The following API function could be tricked into returning information for a different user if the mutable username string is intentionally or unintentionally modified by another thread while this function is using it:

string GetPersonalInfo( string username, string password )
{
    string stored_password = DBQuery.GetPasswordFor( username );
    if (password == stored_password)
    {
        //another thread modifies the mutable 'username' string
        return DBQuery.GetPersonalInfoFor( username );
    }
}

Security isn't just about 'access control', it's also about 'safety' and 'guaranteeing correctness'. If a method can't be easily written and depended upon to perform a simple calculation or comparison reliably, then it's not safe to call it, but it would be safe to call into question the programming language itself.

恬淡成诗 2024-07-12 08:22:40

我知道这是一个障碍,但是...
它们真的是一成不变的吗?
考虑以下。

public static unsafe void MutableReplaceIndex(string s, char c, int i)
{
    fixed (char* ptr = s)
    {
        *((char*)(ptr + i)) = c;
    }
}

...

string s = "abc";
MutableReplaceIndex(s, '1', 0);
MutableReplaceIndex(s, '2', 1);
MutableReplaceIndex(s, '3', 2);
Console.WriteLine(s); // Prints 1 2 3

您甚至可以将其作为扩展方法。

public static class Extensions
{
    public static unsafe void MutableReplaceIndex(this string s, char c, int i)
    {
        fixed (char* ptr = s)
        {
            *((char*)(ptr + i)) = c;
        }
    }
}

这使得以下工作

s.MutableReplaceIndex('1', 0);
s.MutableReplaceIndex('2', 1);
s.MutableReplaceIndex('3', 2);

结论:它们处于编译器已知的不可变状态。 当然,上述内容仅适用于 .NET 字符串,因为 Java 没有指针。 然而,在 C# 中使用指针可以使字符串完全可变。 这不是指针的用途、实际用途或安全使用方式; 然而这是可能的,从而改变了整个“可变”规则。 通常不能直接修改字符串的索引,这是唯一的方法。 有一种方法可以通过禁止字符串的指针实例或在指向字符串时进行复制来防止这种情况,但两者都没有完成,这使得 C# 中的字符串并非完全不可变。

I know this is a bump, but...
Are they really immutable?
Consider the following.

public static unsafe void MutableReplaceIndex(string s, char c, int i)
{
    fixed (char* ptr = s)
    {
        *((char*)(ptr + i)) = c;
    }
}

...

string s = "abc";
MutableReplaceIndex(s, '1', 0);
MutableReplaceIndex(s, '2', 1);
MutableReplaceIndex(s, '3', 2);
Console.WriteLine(s); // Prints 1 2 3

You could even make it an extension method.

public static class Extensions
{
    public static unsafe void MutableReplaceIndex(this string s, char c, int i)
    {
        fixed (char* ptr = s)
        {
            *((char*)(ptr + i)) = c;
        }
    }
}

Which makes the following work

s.MutableReplaceIndex('1', 0);
s.MutableReplaceIndex('2', 1);
s.MutableReplaceIndex('3', 2);

Conclusion: They're in an immutable state which is known by the compiler. Of couse the above only applies to .NET strings as Java doesn't have pointers. However a string can be entirely mutable using pointers in C#. It's not how pointers are intended to be used, has practical usage or is safely used; it's however possible, thus bending the whole "mutable" rule. You can normally not modify an index directly of a string and this is the only way. There is a way that this could be prevented by disallowing pointer instances of strings or making a copy when a string is pointed to, but neither is done, which makes strings in C# not entirely immutable.

魔法少女 2024-07-12 08:22:40

其中一个因素是,如果 String 是可变的,则存储 String 的对象必须小心存储副本,以免其内部数据在没有通知的情况下发生更改。 鉴于 String 是一种像数字一样相当原始的类型,如果可以将它们视为按值传递,即使它们是按引用传递(这也有助于节省内存),那就太好了)。

One factor is that, if Strings were mutable, objects storing Strings would have to be careful to store copies, lest their internal data change without notice. Given that Strings are a fairly primitive type like numbers, it is nice when one can treat them as if they were passed by value, even if they are passed by reference (which also helps to save on memory).

所谓喜欢 2024-07-12 08:22:40

String 不是原始类型,但您通常希望将其与值语义一起使用,即像值一样。

价值观是你可以相信的东西,不会在你背后改变。
如果你写:String str = someExpr();
除非您对 str 执行某些操作,否则您不希望它发生更改。

String 作为一个 Object 具有天然的指针语义,为了获取值语义,它也需要是不可变的。

String is not a primitive type, yet you normally want to use it with value semantics, i.e. like a value.

A value is something you can trust won't change behind your back.
If you write: String str = someExpr();
You don't want it to change unless YOU do something with str.

String as an Object has naturally pointer semantics, to get value semantics as well it needs to be immutable.

南…巷孤猫 2024-07-12 08:22:40

这主要是出于安全原因。 如果您不能相信您的 String 是防篡改的,那么保护系统的安全就会困难得多。

It's largely for security reasons. It's much harder to secure a system if you can't trust that your Strings are tamperproof.

停顿的约定 2024-07-12 08:22:40

不变性很好。 请参阅有效的 Java。 如果每次传递字符串时都必须复制它,那么这将是很多容易出错的代码。 您还不清楚哪些修改会影响哪些引用。 就像整数必须是不可变的才能像 int 一样,字符串也必须是不可变的才能像基元一样。 在 C++ 中,按值传递字符串可以实现这一点,而在源代码中没有明确提及。

Immutability is good. See Effective Java. If you had to copy a String every time you passed it around, then that would be a lot of error-prone code. You also have confusion as to which modifications affect which references. In the same way that Integer has to be immutable to behave like int, Strings have to behave as immutable to act like primitives. In C++ passing strings by value does this without explicit mention in the source code.

段念尘 2024-07-12 08:22:40

几乎所有规则都有一个例外:

using System;
using System.Runtime.InteropServices;

namespace Guess
{
    class Program
    {
        static void Main(string[] args)
        {
            const string str = "ABC";

            Console.WriteLine(str);
            Console.WriteLine(str.GetHashCode());

            var handle = GCHandle.Alloc(str, GCHandleType.Pinned);

            try
            {
                Marshal.WriteInt16(handle.AddrOfPinnedObject(), 4, 'Z');

                Console.WriteLine(str);
                Console.WriteLine(str.GetHashCode());
            }
            finally
            {
                handle.Free();
            }
        }
    }
}

There is an exception for nearly almost every rule:

using System;
using System.Runtime.InteropServices;

namespace Guess
{
    class Program
    {
        static void Main(string[] args)
        {
            const string str = "ABC";

            Console.WriteLine(str);
            Console.WriteLine(str.GetHashCode());

            var handle = GCHandle.Alloc(str, GCHandleType.Pinned);

            try
            {
                Marshal.WriteInt16(handle.AddrOfPinnedObject(), 4, 'Z');

                Console.WriteLine(str);
                Console.WriteLine(str.GetHashCode());
            }
            finally
            {
                handle.Free();
            }
        }
    }
}
贱贱哒 2024-07-12 08:22:40

Java 中的 String 并不是真正不可变的,您可以使用反射和/或类加载来更改它们的值。 您不应该依赖该财产来获得安全。
有关示例,请参阅:Java 中的魔术

Strings in Java are not truly immutable, you can change their value's using reflection and or class loading. You should not be depending on that property for security.
For examples see: Magic Trick In Java

随心而道 2024-07-12 08:22:40

不变性与安全性的联系并不那么紧密。 为此,至少在 .NET 中,您可以获得 SecureString 类。

稍后编辑:在 Java 中,您会发现 GuardedString,一个类似的实现。

Immutability is not so closely tied to security. For that, at least in .NET, you get the SecureString class.

Later edit: In Java you will find GuardedString, a similar implementation.

街角卖回忆 2024-07-12 08:22:40

在 C++ 中让字符串可变的决定会导致很多问题,请参阅 Kelvin Henney 撰写的关于 Mad COW 的优秀文章疾病

COW = 写入时复制。

The decision to have string mutable in C++ causes a lot of problems, see this excellent article by Kelvin Henney about Mad COW Disease.

COW = Copy On Write.

佼人 2024-07-12 08:22:40

这是一个权衡。 String 进入 String 池,当您创建多个相同的 String 时,它们共享相同的内存。 设计者认为这种内存节省技术对于常见情况很有效,因为程序往往会大量处理相同的字符串。

缺点是连接会产生大量额外的 String ,这些字符串只是过渡性的,只会变成垃圾,实际上会损害内存性能。 在这些情况下,您可以使用 StringBufferStringBuilder(在 Java 中,StringBuilder 也在 .NET 中)来保留内存。

It's a trade off. Strings go into the String pool and when you create multiple identical Strings they share the same memory. The designers figured this memory saving technique would work well for the common case, since programs tend to grind over the same strings a lot.

The downside is that concatenations make a lot of extra Strings that are only transitional and just become garbage, actually harming memory performance. You have StringBuffer and StringBuilder (in Java, StringBuilder is also in .NET) to use to preserve memory in these cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文