简体   繁体   English

Java中的最终数组

[英]final array in Java

The following code in Java uses a final array of String and there is no question about it. Java 中的以下代码使用finalString数组,对此毫无疑问。

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

It displays the following output on the console.它在控制台上显示以下输出。

I can never change

The following code also goes without any question.以下代码也毫无疑问。

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    //CONSTANT_ARRAY={"I", "can", "never", "change"}; //Error - can not assign to final variable CONSTANT_ARRAY.
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

Obviously, the commented line causes the specified error because we are trying to reassign the declared final array of type String .显然,注释行会导致指定的错误,因为我们正在尝试重新分配已声明的String类型的final数组。


What about the following code.下面的代码怎么样。

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    CONSTANT_ARRAY[2] = "always";  //Compiles fine.
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

and it displays I can always change means that we could manage to modify the value of the final array of type String .它显示I can always change意味着我们可以设法修改String类型的final数组的值。 Can we ever modify the entire array in this way without violating the rule of final ?我们可以在不违反final规则的情况下以这种方式修改整个数组吗?

final in Java affects the variable , it has nothing to do with the object you are assigning to it. Java 中的final影响变量,它与您分配给它的对象无关。

final String[] myArray = { "hi", "there" };
myArray = anotherArray; // Error, you can't do that. myArray is final
myArray[0] = "over";  // perfectly fine, final has nothing to do with it

Edit to add from comments: Note that I said object you are assigning to it .编辑以从评论中添加:请注意,我说的是您要分配给它的对象 In Java an array is an object.在 Java 中,数组是一个对象。 This same thing applies to any other object:这同样适用于任何其他对象:

final List<String> myList = new ArrayList<String>():
myList = anotherList; // error, you can't do that
myList.add("Hi there!"); // perfectly fine. 

You are misinterpreting the final implementation.你误解了最终的实现。 final applies to the array object reference, which means once it is initiated, the reference can never change but the array its self can be populated. final适用于数组对象引用,这意味着一旦它被启动,引用就永远不会改变,但可以填充数组自身。 "Its not violating the rules" you have specified only one rule about the reference change which is working accordingly. “它没有违反规则”您只指定了一条有关参考更改的规则,该规则相应地起作用。 If you want the values should also never change you should go for Immutable lists ie如果您希望这些值也永远不会改变,您应该选择不可变列表,即

List<String> items = Collections.unmodifiableList(Arrays.asList("I", "can", "never", "change"));

You can only make it so the array reference can't be changed.您只能使其无法更改数组引用。 If you want the elements to be unable to be changed, you need to use an unmodifiable collection of some kind.如果您希望元素无法更改,则需要使用某种不可修改的集合。

当你声明一个数组为final时,你可以改变数组中的元素,但是你不能改变这个数组的引用。

final only guarantees immutability of primitives. final 只保证原语的不变性。 And also guarantees that a variable is assigned only once.并且还保证一个变量只分配一次。 If an object is mutable you can change the content of it event it defined as final.如果一个对象是可变的,您可以更改它定义为 final 的事件的内容。 You may check immutable collections for your needs.您可以根据需要检查不可变集合。 Such as Collections.unmodifiableList() http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#unmodifiableList(java.util.List )比如 Collections.unmodifiableList() http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#unmodifiableList(java.util.List )

The reference to the array object is final (can not change eg in case you would attempt to associate a different Java array object (instance of String[]) to the same final variable...you'd get a compile time error).对数组对象的引用是最终的(不能更改,例如,如果您尝试将不同的 Java 数组对象(String[] 的实例)与同一个最终变量相关联……您会得到编译时错误)。

BUT the fields of the final array object in your example are not final, and so you can modify their value.但是示例中最终数组对象的字段不是最终的,因此您可以修改它们的值。 ...while the Java object you created, CONSTANT_ARRAY, after receiving an initial value, will have that value "forever" == until the JVM stops. ...而您创建的 Java 对象 CONSTANT_ARRAY 在收到初始值后,将“永远”拥有该值 == 直到 JVM 停止。 :) It will be the same String Array instance "forever". :) 它将是“永远”相同的字符串数组实例。

Final variables in Java are not a big deal, just spend some time to digest the topic/idea carefully. Java 中的最终变量没什么大不了的,只需花一些时间仔细消化主题/想法即可。 :-) :-)
I suggest to all of those who are uncertain to meditate over this page, for example: https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4我建议所有不确定的人在此页面上进行冥想,例如: https : //docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4

Let me cite the respective part:让我引用相应的部分:

" Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object. "一旦一个 final 变量被赋值,它总是包含相同的值。如果一个 final 变量持有一个对象的引用,那么对象的状态可能会被对对象的操作改变,但变量将始终引用同一个对象。

This applies also to arrays, because arrays are objects;这也适用于数组,因为数组是对象; if a final variable holds a reference to an array, then the components of the array may be changed by operations on the array, but the variable will always refer to the same array.如果最终变量持有对数组的引用,则数组的组成部分可能会因对数组的操作而改变,但该变量将始终引用同一个数组。 "

The value of the variable CONSTANT_ARRAY cannot change.变量 CONSTANT_ARRAY 的值不能改变。 That variable contains a (reference to an) array.该变量包含一个(对一个)数组的引用。 However, the contents of the array can change.但是,数组的内容可以更改。 Same thing happens when you declare any kind of final variable that is not a simple scalar type (eg an object).当您声明任何类型的非简单标量类型(例如对象)的最终变量时,也会发生同样的事情。

Be careful how you name your variables.小心你如何命名你的变量。 :-) Calling it a CONSTANT_ARRAY doesn't make the contents of the array unchangeable. :-) 将其称为 CONSTANT_ARRAY 不会使数组的内容不可更改。

Here's a good reference: The final word on final这是一个很好的参考: final的最后一句话

When a variable is declared with the final keyword, its value can't be modified, essentially, a constant.当一个变量用 final 关键字声明时,它的值不能被修改,本质上是一个常量。 This also means that you must initialize a final variable.这也意味着您必须初始化一个最终变量。 If the final variable is a reference , this means that the variable cannot be re-bound to reference another object , but the internal state of the object pointed by that reference variable can be changed ie you can add or remove elements from the final array or final collection.如果最终变量是一个引用,这意味着该变量不能被重新绑定以引用另一个对象,但该引用变量所指向的对象的内部状态可以改变,即您可以在最终数组中添加或删除元素或最后的集合。

    final int[] res;
    int[] res1;
    int[] res2 = new int[1];
    res2[0]=20;

    res1=res2;
    res1=res2;//no error
    System.out.println("res1:"+res1[0]);

    res = res2;//only once
   //res = res2;//error already initialised
    res2[0]=30;

    System.out.println("res:"+res[0]);     

output:: res1:20 res:30输出:: res1:20 res:30

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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