数组的 getter 和 setter
我有一些关于数组的 getter 和 setter 的问题。假设我们有一个这样的类,它在其构造函数中创建一个数组的私有副本:
import java.util.Arrays;
public class Foo
{
private int[] array;
public Foo(int[] array) {
this.array = Arrays.copyOf(array, array.length);
}
}
我们希望该数组只能通过 getter 和 setter 进行访问/修改。如果我们有一个如下所示的 getter:
public int[] getArray() {
return array;
}
它违背了 getter 的目的,因为我们返回一个允许用户直接修改数组元素的引用。例如
Foo foo = new Foo(someArray);
...
int[] bar = foo.getArray();
bar[0] = 123; // Now foo.array[0] = 123 and we haven't used a setter!
,我们大概需要这样的东西:
public int getElement(int index) {
return array[index];
}
对于设置者来说也是如此。但是,如果我们在每个元素的基础上进行操作,我们还需要提供一种获取长度的方法:
public int getArrayLength() {
return array.length;
}
对于一维数组来说这已经有点混乱了,但是假设我们有一个多维数组相反:
import java.util.Arrays;
public class Foo
{
private int[][][] array;
public Foo(int[][][] array) {
// Code for making a deep copy here
}
public int getElement(int i, int j, int k) {
return array[i][j][k];
}
public void setElement(int i, int j, int k, int value) {
array[i][j][k] = value;
}
public int getArrayLength() {
return array.length;
}
public int getArrayLength(int i) {
return array[i].length;
}
public int getArrayLength(int i, int j) {
return array[i][j].length;
}
}
对于这样一个琐碎的任务来说,这是很多代码,更重要的是,实际使用起来很混乱。我们真的必须以这样的方式结束吗?还是有更好的方法来做到这一点?我查遍了所有地方,似乎没有一个“标准做法”。
I have a few questions about getters and setters for arrays. Suppose we have a class like this, which makes a private copy of an array in its constructor:
import java.util.Arrays;
public class Foo
{
private int[] array;
public Foo(int[] array) {
this.array = Arrays.copyOf(array, array.length);
}
}
We want the array to only be accessed/mutated via the getters and setters. If we have a getter that looks like this:
public int[] getArray() {
return array;
}
it defeats the purpose of the getter as we're returning a reference that allows the user to directly modify the elements of the array. e.g.
Foo foo = new Foo(someArray);
...
int[] bar = foo.getArray();
bar[0] = 123; // Now foo.array[0] = 123 and we haven't used a setter!
So presumably we need something like this:
public int getElement(int index) {
return array[index];
}
Similarly for setters. But if we're doing things on a per-element basis, we're also going to need to provide a means of getting the length:
public int getArrayLength() {
return array.length;
}
This is already a little messy for a 1-dimensional array, but say we have a multidimensional array instead:
import java.util.Arrays;
public class Foo
{
private int[][][] array;
public Foo(int[][][] array) {
// Code for making a deep copy here
}
public int getElement(int i, int j, int k) {
return array[i][j][k];
}
public void setElement(int i, int j, int k, int value) {
array[i][j][k] = value;
}
public int getArrayLength() {
return array.length;
}
public int getArrayLength(int i) {
return array[i].length;
}
public int getArrayLength(int i, int j) {
return array[i][j].length;
}
}
This is a lot of code for such a trivial task, and more importantly it's a mess to actually use. Do we really have to end up with something like this, or is there a better way to do it? I've looked all over the place and there doesn't seem to be a "standard practice" for this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
多维数组也是一维数组:
int[a][b][c]
实际上只是int[a*b*c]
,所以问题归结为,如何安全地提供访问?就这么简单:就是这样。
调用者拥有数组的安全副本,并且可以以完全正常的数组使用方式使用它。不需要委托方法。
A multi-dimensional array is also a 1-dimensional array:
int[a][b][c]
is really justint[a*b*c]
, so the problem boils down to, how do you provide access safely? Simply like this:That's it.
Callers have a safe copy of the array and can use it in the full normal way arrays are used. No need for delegator methods.
您认为
ArrayList
或之前的Vector
会做什么?我认为更好的问题是,为什么此时您要公开
Foo
完全由数组支持?如果您尝试封装它,则不需要到处都有访问器和设置器。如果您只是尝试围绕数组创建一个类包装器,那么我建议您有一个接口,将其称为IntList
或其他名称,并使Foo
成为具体实现这是有清单支持的。What do you think
ArrayList
does, orVector
before it?I think the better question is why, at this point, are you exposing that
Foo
is backed by an array at all? If you're trying to encapsulate it, you don't need to have accessors and setters all over the place. If you're just trying to create a class wrapper around the array, then I would suggest you have an interface, call itIntList
or something, and makeFoo
a concrete implementation that's backed by the list.关于第一部分,你的 getter 看起来不像构造函数吗?
In relation to the first part could your getter not look like the constructor?
我为多维通用数组编写了一个小型 API。无论你的尺寸是多少,每个元素都有 getter 和 setter。
github 上的 MDDAJ
这是一个示例:创建一个 5 维字符串数组:
Bohemian 已经写过你只能使用一个方面。在这种情况下,类 PDAPSeudo 内部也具有一维。但 API 为您提供了像多维数组一样的访问
I wrote a small API for multidimensional generic arrays. There you have getters, setters for each element, whatever your dimensions are.
MDDAJ on github
Here is a example: creating a 5 dimensional string array:
Bohemian already wrote you can use only one dimension. In this case the class PDDAPSeudo internal have one dimension, too. But the API provides you access like a multi dimensional array