是否在Java中返回数组是安全的?

时间:2013-10-27 02:32:44

标签: java arrays pointers

我是Java的新鸟,我对使用Java返回数组感到困惑。 以下是我的代码:

public class Pointer{
    private final int[] data;
    Pointer(){
        data = new int[4];
        data[0] = 1;
        data[1] = 2;
        data[2] = 3;
        data[3] = 4;
    }
    public int[] test(){
        return data;
    }
    public void print(){
        int length = data.length;
        int j;
        for(j = 0; j < length; j++){
            System.out.println(data[j]);
        }
    }
    static public void main(String[] argv){
        Pointer i = new Pointer();
        int[] re = i.test();
        i.print();
        re[2] = 1;
        i.print();
    }
}

我虽然返回了一个int数组,而不是指向它的指针,所以当我写re [2] = 1时不应该更改数据。如何使这个指针对象不可变?

3 个答案:

答案 0 :(得分:2)

首先,看看Josh Bloch的优秀书籍 Effective Java 中不可变类章节的documentation。我知道这个网站看起来像是在1997年制作的,但不要让那个打扰你。信息很好。

为了使您的类不可变,您不能允许对可变的私有数据的mutator方法(即setter)访问器(即getter)。这否定了private - 并且创造了一个漏洞的抽象。

您发现了后者的一个实例。您通过getter公开的数组是可变的。这使你的班级变得可变。无法使数组成为不可变的。

你有选择。以下是一些:

  • 在你的getter中,返回类中数组的副本。
  • 没有getter,但允许getValue(int index)之类的东西检索给定索引处的数组值(如果索引超出范围,则会像IllegalArgumentException一样进行错误处理)。
  • 在getter中,返回一个由Collections.unmodifiableList(Arrays.asList(data));之类的数组构造的不可变集合。有关文档,请参阅here

答案 1 :(得分:0)

数组是Java中的对象,对象通过引用传递(即使引用按值传递)。

您无法通过值传递数组。

您可以做的是返回数组的副本。这种方式对返回数组的更改不会影响Pointer内的内部数组(如果这是您想要的行为)。

public int[] test(){
    return data.clone();
}

答案 2 :(得分:0)

返回数组的唯一情况是安全的是数组为空时。否则我们需要返回一份副本。有两种方法可以复制1)arr.clone()2)Arrays.copyOf()