簡體   English   中英

Java Create Wrapper類與可變成員不可變

[英]Java Create Wrapper Class Immutable with Mutable members

目前,我有一個名為MatrixValue的類,我想將該類做成一個不可變的對象,以便與MatrixValue實例進行交互的所有方法都不能更改其內部矩陣。 但是,問題是成員變量之一是一個稱為RealMatrix的可變對象,該對象存儲矩陣的所有實際數據。 我已經將防御性復制放入構造函數中,並且擺脫了任何mutator方法。 到目前為止,這是我班上的樣子:

public final class MatrixValue extends ExpressionValue{

    /**
     * 
     */
    private static final long serialVersionUID = -4231050452116360135L;
    private final RealMatrix matrix;

    public MatrixValue(RealMatrix matrix){
        this.matrix = new Array2DRowRealMatrix(matrix.getData());
    }

    public MatrixValue(double[][] values){
        matrix = new Array2DRowRealMatrix(values);
    }

    public RealMatrix getMatrix() {
        return matrix;
    }

    @Override
    public String toString(){
        return matrix.getRowDimension() + "," + matrix.getColumnDimension();
    }
}

現在的問題是,如果有人調用matrixValue.getMatrix().setEntry(row, col, value); 他們可以有效地更改最終RealMatrix成員變量的值。 但是,我仍然希望能夠返回有關RealMatrix信息。 解決此類不變性的最佳方法是什么?

編輯 :還請記住,某些矩陣可能會占用大量內存,因此,如果可能的話,我希望使用一種解決方案,以最大程度地減少不必要信息的重復。

考慮在RealMatrix上使用接口。 可能的接口可能稱為矩陣。 然后,您的內部表示形式可以使用RealMatrix,然后在提供外部API的地方,可以代替使用RealMatrix的返回類型,而返回Matrix。

class RealMatrix implements {
// getters and setters
}

interface Matrix  {
// only getters
}

最簡單的方法可能是從getMatrix()方法返回matrix的防御性副本。 您可以每次克隆它,然后在方法中返回,或者在構造函數中創建一個副本,然后僅在方法中返回相同的副本。

但是,我認為MatrixValue的意圖是什么。 如果它是RealMatrix的不可變表示RealMatrix ,我將考慮為RealMatrixMatrixValue組成一個接口,如下所示:

interface Matrix {
  // getters for Matrix
}

RealMatrixMatrixValue將實現以下接口:

public class RealMatrix implements Matrix {
    // getters for Matrix
    // setters for RealMatrix
}

public class MatrixValue extends ExpressionValue implements Martix {
    public MatrixValue(RealMatrix matrix){
        this.matrix = new Array2DRowRealMatrix(matrix.getData());
    }

    // getters for Matrix
}

這提供了這樣的意圖,即RealMatrixMatrixValue分別是Matrix可變和不可固定的表示形式,並允許API調用者從MatrixValue獲取值,但不能對其進行修改。

順便說一下,在MatrixValue構造函數中創建Array2DRowRealMatrix的新實例可能不足以進行防御性復制,因為double[][]數組可以在外部進行修改。 您需要使用Arrays.copyOfSystem.arraycopy為數組的每個維度制作數組的副本,以免發生突變。

暫無
暫無

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

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