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

返回Java中的数组是否安全?,java,arrays,pointers,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(){

我是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[]数据;
指针(){
数据=新整数[4];
数据[0]=1;
数据[1]=2;
数据[2]=3;
数据[3]=4;
}
公共int[]测试(){
返回数据;
}
公开作废印刷品(){
int length=data.length;
int j;
对于(j=0;j

我想我返回了一个int数组,而不是指向该数组的指针,因此在我写re[2]=1时不应该更改数据。如何使此指针对象不可变

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

不能按值传递数组本身

您可以做的是返回数组的副本。这样,对返回数组的更改不会影响
指针内的内部数组(如果这是您想要的行为)


首先,看看Josh Bloch的优秀著作《有效Java》中的不可变类一章。我知道这个网站看起来像是1997年制作的,但别让它打扰你。信息是好的

为了使您的类是不可变的,您不能允许对可变的私有数据使用mutator方法(即setter)或accessor(即getter)。这否定了
私有性
,并创建了一个泄漏的抽象

你发现了后者的一个例子。通过getter公开的数组是可变的。这使得您的类是可变的。没有办法使数组不可变

你有选择。以下是一些:

  • 在getter中,返回类中数组的副本
  • 没有getter,但允许使用类似于
    getValue(int-index)
    的方法在给定索引处检索数组值(如果索引超出范围,则使用类似于
    IllegalArgumentException
    的错误处理)
  • 在getter中,返回由数组构造的不可变集合,如
    Collections.unmodifiableList(Arrays.asList(data))。有关文档,请参阅

返回数组时唯一安全的情况是数组为空。否则我们需要返回一份副本。制作副本有两种方法1)arr.clone()2)Arrays.copyOf()相关:您搜索过吗?或者,您不能在Java中返回数组,只返回对它的引用。如果要返回的数组不是原始引用,则必须复制一个数组或按照其他数组的建议执行。@Radiodef Hi,谢谢您的回答。我将数据声明为final,但这只适用于作为引用的数据,在构造函数之前,我不知道数据有多少元素。在这种情况下,如何避免数据[0]和数据[1]被更改?是否将数据声明为最终数据并不重要。在代码示例中,test()返回数据所持有的值,该值是对数组的引用。(在Java中,它们通常被称为引用,而不是指针,尽管它基本上是指针。)我看到有人发布了一个答案,显示了复制整个数组的快速方法。否则,如果不需要更改返回的数组,请转到上面的链接之一,查看如何返回不可变数组引用。
public int[] test(){
    return data.clone();
}