-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?

5
  • 1
    Related: How to create immutable objects in Java? Commented Oct 27, 2013 at 2:37
  • 3
    Have you searched about it? stackoverflow.com/questions/10339930/final-array-in-java OR stackoverflow.com/questions/3737769/java-unmodifiable-array Commented Oct 27, 2013 at 2: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. Commented Oct 27, 2013 at 2: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? Commented Oct 27, 2013 at 2: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. Commented Oct 27, 2013 at 3:01

3 Answers 3

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.
Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.