0

在下面的代码中,只有一个 StringBuilder 实例,而 test2 和 test3 实际上指向new StringBuilder()

StringBuilder test = new StringBuilder("test");
StringBuilder test2;
StringBuilder test3;
test2 = test;
test3 = test2;

所以我可以附加 test3 它将附加原始测试。

我知道 String 是不可变的,但请使用下面的代码

String test = new String("test");
String test2;
String test3;
test2=test;
test3=test2;

使用相同的逻辑推理,它的行为应该完全相同,但是如果我更改 test3 它与 test 无关,这意味着当我这样做时,test=test2它实际上是在做类似的事情test2=new testtest3 = new test2这对我来说似乎非常不合逻辑。假设我想创建自己的简单字节类,一个表现得像 StringBuilder,一个表现得像 String 在 StringBuilder 类中究竟允许传递实例,而在 String 类中允许它通过使用自动创建一个新实例等号?我不明白我给出的两个示例之间的 test=test2 在逻辑上是如何一致的。在我看来,这实际上是不可预测的不合逻辑。哪一行代码实际上在这两个类之间产生了这种差异?

当您将等号与 StringBuilder 的实例一起使用时,它会传递该实例,但是当您将等号与 String 的实例一起使用时,它会神奇地创建一个新实例。类中的哪一行代码决定了等号的行为方式?我不喜欢这样,因为它实际上改变了等号的含义,所以我想至少知道哪段代码改变了等号的定义。

4

1 回答 1

2

哪一行代码实际上使这两个类之间产生了这种差异

您未显示的代码行。要附加test3为 a string,您需要执行额外的分配:

test3 = test3 + "abc";

(如果您不在这里执行分配,则新生成string的将立即有资格进行垃圾收集,因为没有任何东西持有对它的引用)

附加到test3as a StringBuilder,没有额外的分配:

test3.Append("abc");

假设我想创建自己的简单字节类,一个表现得像 StringBuilder,一个表现得像 String

要创建类似的类StringBuilder,您将创建一个在Append()调用类似的“修改”方法时修改其内部状态的类。要创建类似 的类String,您将创建一个类,该类创建包含由“修改”方法创建的更新状态的类的新实例。这样的方法不会更新它们自己的内部状态。

这都是关于实现不可变类的 - 没有编译器魔法,这只是一个设计决定。

于 2013-06-10T06:57:42.487 回答