为什么我可以在Java中编辑最终数组的内容?

2022-08-31 15:19:12

以下 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] + " ");
    }
  }
}

它在控制台上显示以下输出。

I can never change

如果我们尝试重新分配类型 为 的声明数组,我们会导致错误:finalString

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] + " ");
    }
  }
}

错误:无法分配给最终变量 。CONSTANT_ARRAY

但是,以下代码有效:

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] + " ");
    }
  }
}

它显示

I can always change

这意味着我们可以设法修改类型.我们能否以这种方式修改整个数组,而不会违反 不可变的规则 ?finalStringfinal


答案 1

final在Java中会影响变量,它与分配给它的对象无关。

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

编辑以从评论中添加:请注意,我说的是您要分配给它的对象。在Java中,数组是一个对象。这同样适用于任何其他对象:

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

答案 2

您误解了最终实现。 应用于数组对象引用,这意味着一旦启动,引用就永远不会更改,但可以填充数组本身。“它没有违反规则”,您只指定了一条关于引用更改的规则,该规则正在相应地工作。如果你想要的值也应该永远不会改变,你应该去不可变列表,即final

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