[英]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
,我將考慮為RealMatrix
和MatrixValue
組成一個接口,如下所示:
interface Matrix {
// getters for Matrix
}
RealMatrix
和MatrixValue
將實現以下接口:
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
分別是Matrix
可變和不可固定的表示形式,並允許API調用者從MatrixValue
獲取值,但不能對其進行修改。
順便說一下,在MatrixValue
構造函數中創建Array2DRowRealMatrix
的新實例可能不足以進行防御性復制,因為double[][]
數組可以在外部進行修改。 您需要使用Arrays.copyOf
或System.arraycopy
為數組的每個維度制作數組的副本,以免發生突變。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.