0

由于您无法设置最终变量的值(我假设),例如数组的长度。

Object[] items = new Object[10];

//Not allowed
Object.length = 3;

可以在课堂上将其用作只读字段吗?

4

4 回答 4

7

这取决于您所说的“确定”是什么意思。您无法更改的原因items.length是这length是一个只读字段;创建数组后,它的大小是固定的。items无论是否声明为,您指定的“不允许”行都是无效的final

重要的是要理解创建items变量final只是意味着您将无法更改变量的值以引用不同的数组。变量值是一个引用,而不是数组本身。您无法更改变量引用的数组,但您仍然可以更改数组的内容:

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

如果您想要真正不可变的东西,则不能使用数组。

于 2012-09-05T17:35:09.480 回答
2

C#中的readonly和 java 中的final或多或少是相同的(至少当它们应用于字段时)。每当您将字段标记为 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"

即使字段“地址”是最终的,它也是完全有效的。

此外,不要依赖final来构建任何类型的“安全性”或对某些值的强访问限制,因为它很容易通过反射被打破。(http://stackoverflow.com/questions/4516381/changeing-private-final-fields-via-reflection)

可能不需要所有这些澄清,但有人可能会发现它很有用

干杯,克劳迪奥

于 2012-09-05T17:49:00.263 回答
0

有些人喜欢将所有实例变量保持私有并使用“getter”,例如getLength()方法,但这确实是个人喜好。公共 final 字段没有任何问题;这只是风格。就个人而言,我有时将它们用于非常简单的课程。

于 2012-09-05T17:39:20.377 回答
0

当然,因此将其公开为只读的方法是将成员变量“items”保留在您的类中,并公开一个公共 getter 方法。就像是:

public int getNumItems() {
    return (items == null ? 0 : items.length); //includes null handling using ternary operator
}
于 2012-09-05T17:39:21.470 回答