2012-09-05 94 views

回答

2

只读在C#和最终在Java或多或少是相同的(至少当它们被施加到字段)。无论何时将字段标记为final,只要通过变量初始化或通过对象构造函数进行赋值,编译器将不允许您修改其引用。

但是它不会阻止你改变你引用的对象的内容,做这样的事情:

public class Person { 
    public final String name; 
    public final Address address; 

    public Person(String name, Address address) { 
     this.name = name; 
     this.address = address; 
    } 
} 

//Someplace else 
Person peter = new Person("peter", new Address("Dolphin Cove 993", "Stamford", "CT"); 
peter.address.state = "CA" 

这是即使在外地“地址”是最终完全有效。

此外,不要依赖最终建立任何类型的“安全”或强访问限制的某些价值,因为它可以很容易地通过反思破坏。 (http://stackoverflow.com/questions/4516381/changing-private-final-fields-via-reflection)

所有可能是不需要此澄清,但有人可能会发现它有用

干杯, Claudio

7

这取决于你的意思是“OK”。您无法更改items.length的原因是length是只读字段;数组创建后,其大小是固定的。不管items是否被声明为final,您指定的“不允许”行都将失效。

明白,做一个items可变final只是意味着你将无法改变变量的值是指不同的排列是很重要的。变量值是参考,而不是阵列本身。你不能改变的变量是指阵列,但你仍然可以改变数组的内容:

// Entirely valid... 
items[0] = new Object(); 

如果你想要的东西,这是真正的不可变的,你不能使用数组。

+2

+1空数组是不可变的,但是一个或多个数组是可变的。 –

0

有些人更喜欢将所有实例变量保留为私有的,并使用“getters”一个getLength()方法,但它确实是个人偏好。没有确切的错误与公共最终字段;这只是风格。就个人而言,我有时候会用它们来进行非常简单的课程

+0

如果public final字段持有对可变对象的引用,那么它可能是错误的。在这种情况下,Getter返回不可变视图或对象副本是唯一的方法。 – Rorick

+0

当然,但也可能出现这样的情况,即封闭类与其他实例数据的引用完全相同,即使它是可变的。完全取决于用例。 –

0

当然,所以将它公开为只读的方式是将成员变量的“项目”隐藏在您的类中,并公开getter方法。类似:

public int getNumItems() { 
    return (items == null ? 0 : items.length); //includes null handling using ternary operator 
}