我不是Java程序员。我阅读了关于“final”的文档,并将其理解为“变量的值可以设置一次且仅一次。”
我正在将一些Java翻译成C#。代码未按预期执行。我试图找出原因,并发现最终的一些用途没有意义。
代码段1:
final int[] PRED = { 0, 0, 0 };
...
PRED[1] = 3;
PRED [1]会是0还是3?
代码段2:
final int[] PRED = new int[this.Nf];
for (int nComponent = 0; nComponent < this.Nf; nComponent++) {
PRED[nComponent] = 0;
}
...
PRED[1] = 3;
肯定PRED [0]会保持为0吗?
答案 0 :(得分:6)
我认为当它应用于Java中的数组时,您对final
关键字语义有误解。
在两个Java示例中,数组将保持不变,但其元素可能会更改。您的所有分配都将正确执行,并且存储在数组中的值将会更改。但是,如果你尝试
final int[] PRED = new int[this.Nf];
// some other code
PRED = new int[123]; // <<== Compile error
您将看到编译错误。
将代码翻译为C#时,您可能需要将final
翻译为sealed
(当它应用于class
时)或readonly
(当它适用于成员)。 Java中C#和readonly
数组中final
数组的语义是相同的:您的程序无法重新分配数组,但它可以自由地修改其元素。
最后,在使用final
的情况下,存在一个特定于Java的情况:在C#中根本不需要它:当你需要在Java中的匿名本地类的方法中使用变量时,你必须使变量final
。由于C#没有匿名本地类,因此您需要使用其他内容(也许使用匿名委托)来翻译该段代码。这些代表不限于使用只读变量。
答案 1 :(得分:3)
您在C#中寻找的词是“const”:
const int SOMETHING = 10;
请注意,SIZE也应该是常量。
此外,常量只能是int,bool,string,char等类型(仅限基本类型)。
因此,如果你想要其他东西,比如数组或类,你可以这样做:
static readonly int[] PRED = new int[this.Nf];
静态Readonly意味着精确的const,逻辑上,除了后台稍有不同的定义,它允许你更自由地玩它。 (当你可以 - 你应该定义常量而不是静态只读)
阵列本身在运行期间不会改变,因此您将无法执行此操作:
PRED = new int[3]; // Error
PRED = null; // Error
PRED = PRED; // Error
但是你可以改变PRED阵列中的值:
PRED[0] = 123;
如果您希望拥有只读集合,则可以使用ReadOnlyCollection对象! 如果你也希望那个对象是常量,你可以使用static-readonly组合(你不能使用常量,因为它是一个类),你会得到:
static readonly ReadOnlyCollection<int> PRED = new ReadOnlyCollection<int>(new[] {1, 2, 5, 6});
然后PRED将永远是PRED,并且总是大小为4,并且将始终包含1,2,5,6。
PRED = PRED; // Error (static readonly)
PRED = null; // Error (static readonly)
PRED[1] = 0; // Error (ReadOnlyCollection enforces readonly on the elements)
int i = PRED[1]; // Still works, since you aren't changing the collection.
答案 2 :(得分:2)
final由编译器检查,而不是在运行时检查。因此,如果赋值PRED[1] = 3
无效,它将被编译器捕获,代码甚至无法编译。
此赋值有效,因为final意味着:您无法将另一个值重新赋值给变量。这并不意味着:你不能改变变量引用的对象。
上述作业不会修改PRED
的值。它修改了PRED[1]
的值。如果PRED是列表,则等效值为PRED.set(1, 3)
。哪个可以。不正确的是PRED = new ArrayList<Integer>()
。
答案 3 :(得分:1)
如果你想要一个值只设置一次,而不是在java中使用read,那么在c#或const中,或者在某些情况下应该使用密封,尽管readonly可能更好,如果你只想阅读;)
答案 4 :(得分:1)
正如您所说,final
变量只能设置一次。但改变其价值观是合法的。
答案 5 :(得分:1)
Java final关键字在Java编程语言中在不同条件下使用,具有不同的含义。例如:
声明一个常量方法参数。
声明为final的变量必须在使用之前进行初始化。无法为此变量分配新值,例如(a = b)。但是,如果变量不是基本类型,则可以使用set方法或任何其他公共字段设置其属性。这意味着无法更改对象实例引用,但只要它们本身未被声明为final,就可以更改对象实例的属性。
禁止在正在使用的方法中修改参数。