4

一般来说,如果一个变量被声明为 final,我们不能覆盖该变量的值,但是当我们使用字符串缓冲区时,这并不适用。有人可以告诉我为什么吗?

下面的代码有效!!!!!!

  public static void main(String args[]) {
        final StringBuffer a=new StringBuffer("Hello");
        a.append("Welcome");
        System.out.println(a);
    }

输出:

你好,欢迎

4

4 回答 4

9

来自Java 语言规范(强调我的):

一旦分配了最终变量,它总是包含相同的值。如果最终变量持有对对象的引用,则对象的状态可能会通过对对象的操作而改变,但变量将始终引用同一个对象。

所以可以操作指向的对象的状态a

a.append("Welcome"); //is OK

但不能a用另一个对象重新分配

final StringBuffer a = new StringBuffer("Hello");
a = new StringBuffer("World"); //this wont compile
于 2013-03-21T20:16:24.653 回答
4

您不能对最终变量执行的操作是将其更改为引用另一个对象(或原始值)或 null。

在那里,您总是引用同一个对象,并且与字符串相反,字符串缓冲区不是不可变的。

您必须得到的是变量的值是对字符串缓冲区的引用,而不是该对象的实际内容。

于 2013-03-21T20:13:01.137 回答
0

您应该阅读Mutable 和 Immutable objects

不可变类示例:String、Integer、Long 可变类示例:StringBuffer、Date

在可变对象中,您可以在其构造后更改状态,例如

final StringBuffer a=new StringBuffer("Hello");
a.append("Welcome");

在 immutable 中,您不能在对象构造后更改其状态。

于 2013-03-21T20:25:15.977 回答
0

如果一个变量被声明为final,我们不能覆盖该变量的值

正确的。一旦分配了最终变量,就不能重新分配它。编译器不允许这样做。

但是当我们使用字符串缓冲区时,这并不适用。

是的,它确实。

下面的代码有效!!!!!!

该代码没有出现您描述的问题。它表明引用为 final 的对象仍然可以变异。那是完全不同的事情。

于 2013-03-22T01:15:25.490 回答