1

给定:类没有字段,每个变量都是本地的。littleString 是通过在 Eclipse 中重构 bigString 创建的:

public String bigString()
    {
        StringBuffer bob = new StringBuffer();
        this.littleString(bob);
        return bob.toString();
    }

private void littleString(final StringBuffer bob)
    {
        bob.append("Hello, I'm Bob");
    }

方法 littleString 不应该将 StringBuffer 传回,但实际上是。这里发生了什么样的黑魔法?这打破了我所知道的所有封装规则。我很震惊,言语让我失望。

4

4 回答 4

7

littleString没有将对象传回——它只是使用同一个对象。局部变量bobinbigString()和参数bobin 都littleString()引用同一个对象,因此如果您更改其中一个对象,更改将立即出现在另一个对象中,因为它们都是对同一对象的引用

问题是StringBuffers 是可变的并且具有与之关联的内部状态。某些类型的对象(例如Strings)是不可变的,因此您可以安全地将它们作为方法参数传递,并且您知道它们永远不会被修改。请注意,添加final关键字在这里没有帮助——它只是确保bob永远不会被分配来引用不同的StringBuffer对象。

于 2009-02-12T02:29:44.360 回答
1

它没有传递任何东西。它正在修改您传递引用的 StringBuffer。Java 中的对象不是按值传递的。

于 2009-02-12T02:31:15.870 回答
1

如果您的意思是为什么要修改字符串缓冲区,那是因为您传递了对字符串缓冲区的引用,这允许您调用修改字符串缓冲区对象的公共方法 append。

于 2009-02-12T02:32:11.530 回答
0

上面的答案几乎得到了它,除了没有提到一件小事:java缺少“const-ness”,这意味着你希望一个对象是不可修改的。

“final”很接近,但它仍然不能正常工作。代码片段显示的是如果您将可变对象作为参数传递给其他方法时可能发生的错误。这可以通过使用不可变对象来解决,或者如果为深度 const-ness 添加了某种新关键字。

于 2009-02-12T09:56:03.023 回答