繁体   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