理解Java的“最终”转换为C#

时间:2012-05-02 10:36:04

标签: c# java final

我不是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吗?

6 个答案:

答案 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编程语言中在不同条件下使用,具有不同的含义。例如:

  1. 声明一个常量变量,
  2. 声明一个常量方法参数。

    1. 声明为final的变量必须在使用之前进行初始化。无法为此变量分配新值,例如(a = b)。但是,如果变量不是基本类型,则可以使用set方法或任何其他公共字段设置其属性。这意味着无法更改对象实例引用,但只要它们本身未被声明为final,就可以更改对象实例的属性。

    2. 禁止在正在使用的方法中修改参数。