0

As far as I know and researched, arrays in Java are not objects but they're reference-types. My doubt is, when I want to return an array should I return a deep copy (like you would do with an object) with a clone() method for example, or can I return the variable countaining the array like it was a simple-type variable (ie. int or double) with a get method? For clarification porpuses, I will insert an example code to expose this situation:

public class List
{
    // Instance Variables ----------
    private int[] list1;
    private int[] list2;

   // Constructors ----------
   public List()
   {
     list1 = new int[0]; list2 = new int[0];
   }
   public List(List x)
   {
       list1 = x.getList1();
       list2 = x.getList2();

    }

    // Get methods
    public int[] getList1()
    {
        return list1;
    }

    public int[] getList2()
    {
        return list2;
    }

    // Set methods
    public void setList1(int size)
    {
        list1 = new int[size];
    }

     public void setList2(int size)
    {
        list2 = new int[size];
    }
      // Compare reference between an array and the instance variables
      public boolean equals (int[] x)
    {
        if ( x == list1 || x == list2)
        return true;
        else
        return false;
    }
}

And now I have a TestClass the uses class List like this:

List listx = new List();
int[] listy = listx.getList2();
boolean test = listx.equals(listy);
System.out.printf("Result: " + test );

With this said, when I use the method equals to see if the two arrays share the same reference or adress, I get always the result true!! Am I breaking OOP basic principals with this? Will I loose control because listy is pointing to listx instance variable? Well, I'm really confused with this and I don't know if this is right(being array a non-instantiable class) or If I should send some kind of deepcopy insted of shallow using a Clone method in other to ensure that all basic OOP principals are fulfilled, and with this principals I mean that the class method should be acessed only by the API and that the internal state(instance variables) can only be acessed by the class itself.

absinto10
  • 3
  • 2
  • You are probably much better of using ImmutableList of Guava. – Micha Wiedenmann May 07 '14 at 21:26
  • _"I get always the result true!!"_ `listx.equals(listx);` calls `equals(Object o)` (herited from the `Object` class) and obvioulsy return `true` since `listx` is the same object. – Alexis C. May 07 '14 at 21:26
  • Arrays are objects, but the elements are references. Whether you need deep copying is entirely up to your requirements. – user207421 May 07 '14 at 21:29
  • I'm sorry but I ment, boolean test = listx.equals(listy); It was a long day at work :/ sorry about that!! – absinto10 May 07 '14 at 21:31
  • 1
    That depends on what you want your program to do. Depending on your application logic, sometimes you may need to expose some objects as components of a collection or array so that other classes can operate on them (or even add/remove from the collection or array). Some other times you do not want your objects to be mutated, so you give access to a deep copy only. I don't think that any of the two approaches is, by itself, better practice than the other. – abl May 07 '14 at 21:31
  • Yeah, you need to deep copy if you need to deep copy. (And, as far as I know, there is no in-built "deep copy" function in Cloneable, et al.) – Hot Licks May 07 '14 at 21:40
  • Implementation note: always override hashcode() if you override equals() – salyh May 07 '14 at 21:44

3 Answers3

0

If you want the invoker of the method to be able to modify the original array, you don't need to do a copy. Otherwise, you do.

Check your implementation of equals(). It should be reflexive, symmetric, and transitive, which is not the case on yours.

Community
  • 1
  • 1
Andres
  • 10,561
  • 4
  • 45
  • 63
  • yep I know I'm not implementing the method equals correctly, it was just for the example porpuse and notice that, I only wanted to compare the addresses between an array and the instance variable to check where they're pointing. But I understand what you are saying Andres, thank you very much. – absinto10 May 07 '14 at 21:52
0

You are not breaking OOP principals. However, you are breaking principals of functional programming. Functional programming views leaking of access as losing of control.

Whether or not you want to practice functional programming is up to you, Java doesn't take a stance in that matter.

You may want to consider if it's important not to leak access for this particular class. If you find it important not to leak access then make this class immutable.

You can also guard the instance variables. In this scenario any possible changes to the variables must be handled by the instance class. However, the instance could be modified from separate contexts and result in loss of control. For this reason functional programming only allows immutable classes.

Lindlof
  • 2,152
  • 2
  • 17
  • 26
0

It depends on your use-case if you want to deep copy or not. If your elements are immutable you normally not need to do a deep copy. If they can change, it depends if you want to see the changes in your receiver of the copy or not. Typically when you want a snapshot of the given data you will have to deep copy it. However keep in mind that Arrays are most of the time not a good argument or return type for APIs anyway.

eckes
  • 10,103
  • 1
  • 59
  • 71