在 java 中将对象声明为 final

2022-09-02 22:57:17

有人可以澄清以下代码的意义吗?

class A
{
    int i = 10;

    public void setI(int b)
    {
        i = b;
    }

    public int getI()
    {
        return i;
    }
}

class Test
{    
    public static void main(String args[]) throws Throwable
    { 
        final A ob = new A();
        ob.setI(10);
        System.out.println(ob.getI());
    }
}

对象 A 被声明为 final,但我可以更改此对象的实例变量的值,也可以检索更新的值。那么,将对象声明为最终对象的意义是什么?我知道将基元数据类型声明为 final,这使得该变量成为常量。


答案 1

ob 将无法引用任何其他对象:final 关键字

无法重新分配。但是你可以改变它的内部(它是可变的,如果它最初是)。所以这有效:

  final A ob = new A();
  ob.setI(6)

但这并不能:

  final A ob = new A();
  ob = new A();

答案 2

如果指示任何变量为 final,则表示不希望它在内存中包含的值发生更改。对于基元类型,变量表示的值是实际值。对于对象类型,内存中的值是对对象的引用,而不是对实际对象的引用。

例如,您有:

final int x = 7;
final Object y = new Object();

您可以这样认为数据在内存中表示:

+----------+----------+
|  block   |  value   |
+----------+----------+
|  1001    |    7     |
|  1002    |  2110    |
+----------+----------+

为了便于讨论,让我们省略Java实际如何管理内存的细节(因为我对它也不太了解)。因此,在上面的示例中,块 1001 由变量 x 表示,1002 由 y 表示。两者都是最终变量,这意味着它们表示的值无法更改。在 x 的情况下,它是 7,这是实际值,但在 y 的情况下,2110 只是对另一个内存位置的引用。两者都不能更改,但基元类型变量成为常量的原因是它们表示实际值。但实际上,对于对象类型变量也可以这样说,只是它们表示的常量是引用。因此,最终的关键词在这方面几乎是一致的。

因此,对于最终变量,如果它们是基元类型,它们将不断表示您将其设置为的任何特定值。如果它们是对象/引用类型,它们将不断指向您指向它们的任何对象(无论对象的可变性如何)。