【问题标题】:Way to make my code safe? - Private vs. Public让我的代码安全的方法? - 私人与公共
【发布时间】:2012-01-12 00:10:30
【问题描述】:

A 类的一个实例有一个私有的 ArrayList。该实例负责维护arrayList中存储的数据。

private ArrayList<SomeDataStructure> myPrivateArrayList;

但是,当其他模块请求数据时,A类的这个实例将不得不将数据传递给请求它的人,因此,A类中有公共函数:

public ArrayList<SomeDataStructure> getMyPrivateArrayList ();

我的问题,我应该如何实现这个函数,这样才能保证通过这个公共函数得到arrayList的人不能修改它(即返回值是只读的强>)?

提前致谢!

【问题讨论】:

  • 返回副本?使用Collections.unmodifiableList?

标签: java android oop


【解决方案1】:

我建议改为这样做(如果您的情况允许的话):

private ArrayList<SomeDataStructure> myPrivateArrayList;

public List<SomeDataStructure> getMyPrivateList () {
    return Collections.unmodifiableList(myPrivateArrayList)
}

请注意,公开的数据结构是List 类型而不是ArrayList。我认为(一般来说)一个类的公共接口不应该返回具体类型,而应该返回接口。它简化了诸如此类的任务,还减少了一个类对另一个类的实现的依赖程度。

【讨论】:

    【解决方案2】:

    使用List&lt;SomeDataStructure&gt;,而不是返回类型ArrayList&lt;SomeDataStructure&gt;。然后您可以使用the java.util.Collections.unmodifiableList(...) utility-method 创建您的列表的只读视图:

    public List<SomeDataStructure> getMyPrivateArrayList()
    {
        return Collections.unmodifiableList(myPrivateArrayList);
    }
    

    另一种选择是返回您的列表副本:

    public ArrayList<SomeDataStructure> getMyPrivateArrayList()
    {
        return new ArrayList<SomeDataStructure>(myPrivateArrayList);
    }
    

    (还有其他一些选项,但这些是最常见的方法。)

    但请记住,如果 SomeDataStructure 是可变的,那么上述任何一个的调用者仍然可以改变列表中的任何对象。 (也就是说,他们可以做类似obj.getMyPrivateArrayList().get(0).setProp(null) 的事情。)

    【讨论】:

      【解决方案3】:

      在您的 getMyPrivateArrayList () 函数中执行以下操作:

      public List<SomeDataStructure> getMyPrivateArrayList(){
          return Collections.unmodifiableList(myPrivateArrayList);
      }
      

      Collections.unmodifiableList(someList) 返回只读列表。


      在您的调用类中,如果您尝试修改返回的列表,您将在运行时出错。 例如。

      如果您执行以下操作

      List<SomeDataStructure> readOnlyList=getMyPrivateArrayList();
      readOnlyList.add(new SomeDataStructure());
      

      你会得到以下错误:

      Exception in thread "main" java.lang.UnsupportedOperationException
        at java.util.Collections$UnmodifiableList.add(Collections.java:1160)
        at MainClass.main(MainClass.java:14)
      

      【讨论】:

      • Collections.unmodifiableList返回一个只读的List,所以getMyPrivateArrayList的返回类型至少应该是List,而不是ArrayList
      【解决方案4】:

      您需要获取列表吗?或者您可以简单地将一些访问者转发到列表中吗?您可以定义一些公共函数,例如 get(index),它们只需调用列表中的等效方法并返回结果。这很可能是您想要做的,因为它只允许人们访问您选择的方法,而您不必向他们提供列表本身或浪费 CPU 周期将数据复制到“只读”结构中。

      【讨论】:

        猜你喜欢
        • 2013-05-03
        • 2016-10-17
        • 2014-07-14
        • 1970-01-01
        • 2017-02-17
        • 2013-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多