有人可以澄清以下代码的重要性。
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是什么意义。 我知道将原始数据类型声明为final,这使得该变量保持不变。
答案 0 :(得分:34)
ob将无法引用任何其他对象:final keyword。
无法重新分配。但你可以改变它的内部(它是可变的,如果它是最初的)。 所以这有效:
final A ob = new A();
ob.setI(6)
但这不是:
final A ob = new A();
ob = new A();
答案 1 :(得分:11)
如果您指定任何变量为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只是对另一个存储器位置的引用。两者都不能改变,但原始类型变量成为常量的原因是它们代表实际值。但实际上,你可以对对象类型变量说同样的,只是它们所代表的常量是引用。所以 final 关键字在这方面非常一致。
因此,对于最终变量,如果它们是原始类型,它们将始终表示您设置它们的任何特定值。如果它们是对象/引用类型,它们将不断指向您指向它们的任何对象(无论对象的可变性如何)。
答案 2 :(得分:4)
这意味着以下是不可能的:
final A ob = new A();
ob = new A(); // This is not possible
变量ob
还将引用首次分配给它的类A
的实例。这就是final
关键字在这种情况下的含义。它确实意味着您可以修改ob
的属性,因为它与A
的任何其他实例一样是普通对象。
答案 3 :(得分:3)
如果对象是final
,您可以像往常一样调用任何进行内部更改的方法,但不能将引用重新指定为指向其他对象。尝试这样做:
final A ob = new A();
ob = new A();
并注意代码无法编译。
将此视为常量参考。
答案 4 :(得分:2)
好吧,在对象的情况下,引用的值是对象的地址。因此, ob 的值将是new A();
创建的对象的地址,该对象将是最终的,您将无法更改其值。意思是,你不能为这个参考分配一个新对象。
你不能这样写。
final A ob = new A();
ob= new A(); // not allowed
答案 5 :(得分:1)
在java中,与C ++相反,所有对象都是指针,因此可以更改final
对象,它不能指向任何新的对象,也就是说,你不能将它放在左侧赋值运算符。
答案 6 :(得分:1)
java中不会有任何常量(最终)对象。对象在堆内存区域中创建。我们可以随时修改对象 在java中只有常量(最终)引用: - 意味着你不能修改引用并将其重新分配给任何其他对象,因为它是常量,并且在最终引用之外只引用一个被分配的对象声明。
因此:
final A objectA = new A();
objectA.setI(6);
有效是因为我们只更改对象内容,而不是引用。
可是:
final A objectA = new A();
objectA = new A();
无效,因为您正在尝试修改引用。