Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java创建具有可变成员的不可变包装类_Java_Immutability - Fatal编程技术网

Java创建具有可变成员的不可变包装类

Java创建具有可变成员的不可变包装类,java,immutability,Java,Immutability,目前,我有一个名为MatrixValue的类,我想把它变成一个不可变的对象,这样我所有与MatrixValue实例交互的方法都不能更改其内部矩阵。然而,问题是其中一个成员变量是一个名为RealMatrix的可变对象,它存储矩阵的所有实际数据。我已经在构造函数中加入了防御性复制,并且去掉了任何mutator方法。到目前为止,我的班级是这样的: public final class MatrixValue extends ExpressionValue{ /** *

目前,我有一个名为
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(行、列、值)
它们能够有效地更改最终
RealMatrix
成员变量的值。但是,我仍然希望能够返回有关
RealMatrix
的信息。修复类不变性漏洞的最佳方法是什么


编辑:还请记住,某些矩阵可能会占用大量内存,因此如果可能,我更喜欢一种尽可能减少重复不必要信息的解决方案

考虑在RealMatrix上使用接口。一个可能的接口可以称为Matrix。然后,您可以使用RealMatrix,然后在提供外部API的地方,您可以使用RealMatrix的返回类型而不是返回矩阵

class RealMatrix implements {
// getters and setters
}

interface Matrix  {
// only getters
}

最简单的方法可能是从
getMatrix()
方法返回
matrix
的防御副本。您可以每次克隆它并在方法中返回,或者在构造函数中创建一个副本并在方法中仅返回相同的副本

然而,我会想
MatrixValue
的意图是什么。如果它是<代码> RealMask</代码>的不变表示,我会考虑为<代码> RealMask< <代码>和<代码> MatrxValue<代码>的接口如下:

interface Matrix {
  // getters for Matrix
}
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
}
RealMatrix
MatrixValue
将实现如下接口:

interface Matrix {
  // getters for Matrix
}
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
}
这提供了
RealMatrix
MatrixValue
MatrixValue
的可变和不可变表示的意图,并允许API调用方从
MatrixValue
获取值,但不能修改它


顺便说一下,在
MatrixValue
构造函数中创建
Array2DroArralMatrix
的新实例可能不足以进行防御性复制,因为可以从外部修改
double[][
的数组。您需要为数组的每个维度使用
Arrays.copyOf
System.arraycopy
创建数组副本,以避免变异

可能的重复应该在getMatrix()方法中克隆矩阵。谢谢Michael,我想这就是我要做的。嗨,Wilson,我有一个类似的问题,我喜欢你的接口方法。然而,我使用的getter方法相当复杂,所以在我看来,这种方法违反了DRY原则。在这种情况下,您仍然建议使用它吗?