简体   繁体   中英

Understanding Java's “final” for translation to C#

I am not a Java programmer. I read the documentation on "final", and understand it to mean "a variable's value may be set once and only once."

I am translating some Java to C#. The code does not execute as expected. I tried to figure out why, and found some uses of final that don't make sense.

Code snippet 1:

final int[] PRED = { 0, 0, 0 };
...
PRED[1] = 3;

Will PRED[1] be 0 or 3?

Code snippet 2:

final int[] PRED = new int[this.Nf];
for (int nComponent = 0; nComponent < this.Nf; nComponent++) {
    PRED[nComponent] = 0;
}
...
PRED[1] = 3;

Surely PRED[0] will remain as 0?

I think you have a misunderstanding of the final keyword semantic when it is applied to arrays in Java.

In both Java examples the arrays will remain unchanged, but their elements may be changed. All your assignments will be executed correctly, and the values stored in the array will get changed. However, if you try

final int[] PRED = new int[this.Nf];
// some other code
PRED = new int[123]; // <<== Compile error

you are going to see a compile error.

When translating your code to C#, you may need to translate final either as sealed (when it is applied to a class ), or as readonly (when it is applied to a member). The semantic of readonly arrays in C# and final arrays in Java are the same: your program cannot reassign the array, but it can freely modify its elements.

Finally, there is a Java-specific case when final is used where you wouldn't need it in C# at all: when you need to use a variable inside a method of an anonymous local class in Java, you must make that variable final . Since C# does not have anonymous local classes, you would need to translate that piece of code with something else, perhaps with anonymous delegates. Such delegates are not restricted to using readonly variables.

The word you are looking for in C# is "const":

const int SOMETHING = 10;

Note that the SIZE should be constant as well.

Also, constants can only be of type int, bool, string, char, etc (basic types only).

So if you want something else, such as an array or a class, you can do:

static readonly int[] PRED = new int[this.Nf];

Static Readonly means exactly const, logically, except it is defined a little differently backstage, which allows you to play more freely with it. (When you CAN - you SHOULD define constants instead of static readonly's)

The array itself will not change during the run, so you will not be able to do this:

PRED = new int[3]; // Error
PRED = null; // Error
PRED = PRED; // Error

But you CAN change values INSIDE the PRED array:

PRED[0] = 123;

If you wish to have a readonly collection, you can use the ReadOnlyCollection object! If you also want that object to be constant, you can use the static-readonly combination (you can't use constant because it is a class), and you will get:

static readonly ReadOnlyCollection<int> PRED = new ReadOnlyCollection<int>(new[] {1, 2, 5, 6});

And then PRED will always be PRED, and will always be of size 4, and will always contain 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.

final is checked by the compiler, not at runtime. So if the assignment PRED[1] = 3 was invalid, it would be caught by the compiler and the code wouldn't even compile.

This assignment is valid, because final means: you can't reassign another value to the variable. It doesn't mean: you can't mutate the object referenced by the variable.

The above assignment doesn't modify the value of PRED . It modifies the value of PRED[1] . If PRED was a list, the equivalent would be PRED.set(1, 3) . Which is OK. What would be incorrect would be PRED = new ArrayList<Integer>() .

如果你想要一个值只设置一次,而不是在java中使用readonly在c#,或const中,或者在某些情况下应该使用密封,尽管readonly可能更好,如果你只想阅读;)

As you already stated a final variable can only be set once. But is legal to change its values.

The Java final keyword is used in the Java programming language under different conditions and has different implications. For example:

  1. To declare a constant variable,
  2. To declare a constant method parameter.

    1. A variable declared as final must have an initialization prior to its usage. This variable cannot be assigned a new value such as (a = b). But if the variable is not of primitive type then its properties can be set using the set methods or any other public fields. This means that the object instance reference cannot be changed but the properties of the object instance can be changed as long as they themselves are not declared final.

    2. To prohibit the parameter being modified in the method where it is being used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM