-1

I am a new bird to Java and I am confused about returning an array in Java. Below are my codes:

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();
    }
}

I though I returned an array of int, instead of the pointer to that, so the data should not be changed when I wrote re[2] = 1. How to make this Pointer Object immutable?

ivory
  • 243
  • 4
  • 16
  • 1
    Related: [How to create immutable objects in Java?](http://stackoverflow.com/questions/6305752/how-to-create-immutable-objects-in-java) – Anderson Green Oct 27 '13 at 02:37
  • 3
    Have you searched about it? http://stackoverflow.com/questions/10339930/final-array-in-java OR http://stackoverflow.com/questions/3737769/java-unmodifiable-array – Christian Tapia Oct 27 '13 at 02:39
  • 1
    Yes you can't return an array in Java, only the reference to it is returned. If you want to return an array that is not the original reference you have to either make a copy or do what one of the others are suggesting. – Radiodef Oct 27 '13 at 02:40
  • @Radiodef Hi, thanks for your response. I declare data as final, but that just works for data as a reference, and I do not know how many elements I have for data, before constructor. In this case, how could I avoid data[0], data[1] to be changed? – ivory Oct 27 '13 at 02:53
  • It doesn't matter if you declare data as final. In your code example what happens is test() returns the _value_ that data holds which is a _reference_ to the array. (Usually they are called references in Java, not pointers although it is basically a pointer.) I see somebody's posted an answer that shows a fast way to copy an entire array. Otherwise if you don't need to be able to change the returned array go to one of the above links to see how to return an immutable array reference. – Radiodef Oct 27 '13 at 03:01
  • https://www.tutorialcup.com/java/how-to-return-an-array-in-java.htm – Rahul Gupta May 14 '21 at 13:56

3 Answers3

3

First, take a look at this documentation of the immutable class chapter in Josh Bloch's excellent book Effective Java. I know the site looks like it was made in 1997, but don't let that bother you. The information is good.

In order for your class to be immutable, you can't allow mutator methods (i.e. setters) or accessors (i.e. getters) on private data that are mutable. That negates the private-ness and creates a leaky abstraction.

You discovered an instance of the latter. The array you've exposed via a getter is mutable. This makes your class mutable. There is no way to make arrays immutable.

You have choices. Here are some:

  • In your getter, return a copy of the array in the class.
  • Have no getter, but allow something like getValue(int index) that retrieves the array value at the given index (with error handling like an IllegalArgumentException if the index is out of bounds).
  • In your getter, return an immutable collection constructed from the array like Collections.unmodifiableList(Arrays.asList(data));. See here for the documentation.
Vidya
  • 29,932
  • 7
  • 42
  • 70
0

Arrays are objects in Java and objects are passed by reference (even though a reference is passed by value).

You can not pass the array itself by value.

What you can do is to instead return a copy of the array. This way changes to the returned array will not affect the internal array inside Pointer (if this is the behaviour you want).

public int[] test(){
    return data.clone();
}
Felix Glas
  • 15,065
  • 7
  • 53
  • 82
0

The only case when returning an array is safe is when the array is empty. Otherwise we need to return a copy. There are 2 ways to make a copy 1) arr.clone() 2) Arrays.copyOf()

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275