Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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 为什么要在内部使用MyObject[],但要公开一个列表<;MyObject>;?_Java_Arrays_Collections - Fatal编程技术网

Java 为什么要在内部使用MyObject[],但要公开一个列表<;MyObject>;?

Java 为什么要在内部使用MyObject[],但要公开一个列表<;MyObject>;?,java,arrays,collections,Java,Arrays,Collections,我遇到了一个具有不可变属性的类: MyObject[] allObjs 属性的初始化方式如下: List<MyObject> objs = createAllMyObjects(); allObjs = objs.toArray(new MyObject[objs.size()]); List objs=createAllMyObject(); allObjs=objs.toArray(新的MyObject[objs.size()]); 当它通过访问器公开时,它作为一个列表完成

我遇到了一个具有不可变属性的类:

MyObject[] allObjs
属性的初始化方式如下:

List<MyObject> objs = createAllMyObjects();
allObjs = objs.toArray(new MyObject[objs.size()]);
List objs=createAllMyObject();
allObjs=objs.toArray(新的MyObject[objs.size()]);
当它通过访问器公开时,它作为一个列表完成:

public List<MyObject> getAllMyObjects() {
    return Collections.unmodifiableList(Arrays.asList(allObjs));
}
public List getAllMyObjects(){
返回集合.unmodifiableList(Arrays.asList(allObjs));
}
程序员为什么要这样做?有我不知道的好处吗

性能并不是一个问题,因为OBJ数组只会包含几十个元素

我们似乎在兜圈子

该类是一种工厂,因此它有一个私有构造函数,只公开静态方法(不确定这是否是疯狂的原因)

编辑


我想我的问题是,“为什么不使用一个内部的
列表allObjs
而不是
MyObject[]allObjs
,并返回集合。不可修改列表(allObjs)?”因为这将完成同样的事情。

我认为使用数组代替列表没有任何好处。列表要舒服得多。也许这家伙只是喜欢使用数组:)

我认为这背后的原因可能是数组是不可修改的。但是,您可以将内部列表保留为列表,并在getter中返回它的副本,这样内部列表仍然无法从外部修改

或者使用集合返回的“不可修改”列表。不可修改列表()


在这种情况下,我也看不到任何性能优势,因为来回转换需要一些周期。

这样集合就不可修改,即调用方无法修改成员数组。
无法对数组执行此操作,因此编码人员会将其复制到列表中。

似乎编写者有意返回一个不可变的副本,并且重复了此操作。我假设选择了一个列表作为返回类型,这样就可以使用MyObject类型轻松创建克隆。

有一个很好的理由不返回对内部
MyObject[]
属性的引用。通过引用,调用者可以对数组进行更改

如果没有理由认为结果必须是
列表
,您也可以返回数组的副本:

public MyObject[] getAllMyObjects() {
    MyObject[] result = new MyObject[allObjs.length];
    system.ArrayCopy(allObjs, 0, result, 0, result.length);
    return result;
}
更新,添加问题后: 如果将内部属性更改为列表,则将其包装为不可修改会更容易,这是正确的

类使用数组而不是列表的原因可能是性能。如果数组在对象的生命周期内没有变化(很多),并且多次迭代,那么数组的开销比列表小

如果性能是使用数组的原因,则可以通过存储列表来防止在getter中创建额外的对象,这只是为了返回,即:

allObjsList = Collections.unmodifiableList(createAllMyObjects());
allObjs = allObjsList.toArray(new MyObject[allObjsList.size()]);
像前面一样使用allObjs数组,并在getter中返回存储的列表:

public List<MyObject> getAllMyObjects() {
    return allObjsList ;
}
public List getAllMyObjects(){
返回allObjsList;
}
我看到的唯一原因是“在误用的情况下尽早失败”(如果这个设计选择不是随机的并且有意义,那么意思是他很少信任他的特定客户)

MyObject[]
具体化的,并在运行时检查,而
列表
不是。可以在后者中隐藏非MyObject引用(当然,他在编译时会得到未检查的警告),这将在未定义的将来某个点失败,出现
ClassCastException
,但他不能对
MyObject[]
,这将在误用点立即失败

但是请注意,如果客户机是在泛型之前使用此API的预构建二进制文件,那么没有人会收到未检查的警告,因此如果此代码试图迁移泛型前客户机使用的代码,这是有意义的

(实现相同结果的另一种方法是使用
List
,还需要
Class
,以便后者可以提供运行时类型检查。但这需要另一个构造函数参数,例如,现有客户端不会自动利用该参数。**更新:*这基本上描述了API调用mSauer在第一篇评论中提到,因此我们不必重新发明这个,只需使用那个:)。

在书中,作者实际上说,既然我们有泛型,我们应该只使用collection,而不应该再使用array。就我个人而言,我现在倾向于远离数组,因为集合可以帮助我记住我使用一个集合的意图,例如,将集合与列表作为数组的对立面,而数组并不能真正告诉我关于数据的任何信息


此外,除了快速复制(System.arraycopy())之外,我对集合没有什么不能做的事情,这可能有以下几个原因:

  • 他们不知道自己在做什么。我现在从事的代码似乎是由Java新手和编程新手编写的。不幸的是,遇到设计拙劣的代码远比找到由对平台有深入了解的人编写的好的、干净的、维护良好的代码要普遍得多。这部分是因为下一点
  • 列表
    更改已修补,但不想进行大规模更改。如果代码的其余部分使用该数组,则可能有人不想费心进行所有其他更改
  • 虽然集合是更为面向对象/Java的处理方式,但如果列表是静态的,那么数组实际上“更容易”使用,因为它们仍然可以像集合一样使用
    for(:)
    进行迭代,但可以使用
    []
    而不是
    get()
    进行访问。就我个人而言,这不是使用数组的充分理由,但也许这只是我自己
  • 也许吧