代码之家  ›  专栏  ›  技术社区  ›  Yevgeny Simkin

我可以直接通过getter添加到私有列表吗?

  •  0
  • Yevgeny Simkin  · 技术社区  · 16 年前

    我意识到我会为不仅仅是自己写测试而生气…但我很好奇人们的意见,不仅仅是功能性,所以…这是……

    我有一个有私人名单的班级。我想通过public getmylist()方法添加到私有列表中。

    所以…这能奏效吗?

    public class ObA{
     private List<String> foo;
    public List<String> getFoo(){return foo;}
    }
    
    public class ObB{
       public void dealWithObAFoo(ObA obA){
         obA.getFoo().add("hello");
    
       }
    }
    
    5 回复  |  直到 16 年前
        1
  •  4
  •   Jon Skeet    16 年前

    是的,那绝对有效——这通常是件坏事。(这是因为你真的返回了 参考 到集合对象,而不是集合本身的副本。)

    通常,您希望提供对集合的真正只读访问,这通常意味着返回集合周围的只读包装器。使返回类型成为集合实现的只读接口,并返回实际的集合引用,并没有提供太大的保护:调用方可以轻松地强制转换为“real”集合类型,然后添加,而不会出现任何问题。

        2
  •  2
  •   adrian.tarau    16 年前

    的确,这不是个好主意。不要在外部发布可变成员,如果不能即时提供只读版本,请制作一个副本…

    public class ObA{
      private List<String> foo;
      public List<String> getFoo(){return Collections.unmodifiableList(foo);}
      public void addString(String value) { foo.add(value); }
    }
    
        3
  •  1
  •   user101884    16 年前

    如果你想对此事发表意见,我会删除 getFoo() 调用并添加 add(String msg) remove(String msg) 方法(或您希望公开的任何其他功能)到oba

        4
  •  1
  •   Bill K    16 年前

    在我的经验中,让我接触到收藏似乎总是一件坏事——主要是因为一旦他们出去,几乎不可能控制他们。我已经养成了这样的习惯:不允许直接访问包含它们的类之外的集合。

    这背后的主要原因是,几乎总是有某种业务逻辑附加到数据收集上——例如,在添加时进行验证,或者有一天您可能需要添加第二个密切相关的收集。

    如果您允许像您所说的那样的访问,那么将来很难进行这样的修改。

    哦,还有,我经常发现我最终必须用我存储的对象存储更多的数据——所以我创建了一个新对象(只在存放集合的“容器”中知道),并在将对象放入集合之前将其放入该对象中。

    如果您一直将集合锁定,那么这是一个微不足道的重构。试着想象一下,在某些情况下,如果你不把收藏锁起来,你会多么困难…

        5
  •  1
  •   Peter Lawrey    16 年前

    如果您想支持对foo添加和删除函数,我建议使用add foo()和remove foo()方法。理想情况下,您可以通过为所需的每一项功能创建一个方法来同时消除getfoo。这就清楚地说明了调用者将在列表上执行的函数。