簡體   English   中英

即使我已經將Face類聲明為final類,它似乎也不是一成不變的,該如何糾正呢?

[英]My Face class does not seem to be immutable even though I already declared it as final, how do I correct it?

我正在嘗試使我的Face類不可變,以使Face對象一旦初始化就不會更改。 這是我到目前為止的內容:

public class Face{
  protected final int[][] grid;
  protected Face half;

  public Face(int[][] grid){
    this.grid = grid;
  }


  public Face rotateRight(){
    int rows = 3;
    int cols = 3;
    int[][] transposedArray = new int[3][3];

    for (int i = 0; i<rows; i++){
      for (int j = 0; j<cols; j++){
        transposedArray[i][j]=grid[rows-j-1][i];
      }
    }

    return new Face(transposedArray);
  }

  public Face rotateLeft(){
    int rows = 3;
    int cols = 3;
    int[][] transposedArray = new int[3][3];

    for (int i = 0; i < 3; i++){
      for (int j = 0; j < 3; j++){
        transposedArray[2-j][i] = grid[i][j];
      }
    }
    return new Face(transposedArray);
  }

  public Face rotateHalf(){
    half = this.rotateRight();
    half = half.rotateRight();
    return half;
  }

  public int[][] getGrid(){
    return (this.grid).clone();
    }

  public String toString(){
    String str = "";
    for (int i = 0; i<3;i++){
      for (int j = 0; j<3; j++){
        str += String.format("%02d",grid[i][j]);
      }
    }
    String str1 = str.substring(0,6);
    String str2 = str.substring(6,12);
    String str3 = str.substring(12,18);
    return str1+"\n"+str2+"\n"+str3;
  }
}

但是,當我嘗試運行以下命令時:

int[][] g = f.getGrid();
g[1][1] = 9;

我希望f保持為

010203
040507
070809

但我最終得到

010203
040906
070809

代替。 即使我已經將該類聲明為final,我的Face對象也不會保持不變嗎?

您需要在構造函數中創建輸grid的防御性副本。

同樣,這些字段也應該是private ,並且該類也應該是final ,盡管我懷疑最后兩點不是造成問題的原因。

未經測試:

  public Face(int[][] grid){
    int temp[][] = new int[ grid.length ][];
    for( int i = 0; i < temp.length; i++ ) 
      temp[i] = Arrays.copyOf( grid[i], grid[i].length );
    this.grid = temp;
  }

您的問題可能是您的構造函數沒有克隆傳入的數組。 因此,也許創建Face類實例的代碼稍后會操縱它傳遞給新Face對象的數組!

不幸的是,沒有辦法在Java中創建真正的不可變數組。 將數組聲明為final只會阻止您整體更改數組,仍然可以更改該數組中的各個行,列,插槽。

如果要使用不可變的集合,則需要打開實際的Collection類,然后使用Collections類中的方法在其上創建不可修改的視圖。

使用clone時要小心。

在陣列上,它會進行淺表復制。 以下代碼片段對其進行了更好的解釋:

int[] c0 = new int[]{1, 2, 3};
int[] c1 = new int[]{4, 5, 6};
int[] c2 = new int[]{7, 8, 9};
int[][] grid = new int[][]{c0, c1, c2};
int[][] cloned = grid.clone();

assert cloned[0] == c0;
assert cloned[1] == c1;
assert cloned[2] == c2;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM