6

Almost all methods in CopyOnWriteArrayList use getArray() insted of direct appeal to array. Is there a reason for this behavior? For example :

public int size() {
    return getArray().length;
}

or

    public int indexOf(Object o) {
    Object[] elements = getArray();
    return indexOf(o, elements, 0, elements.length);
}
Waka Waka
  • 95
  • 1
  • 7
  • @AxelH it doesn't. It's a simple package-private final method with `return array;`. Probably some JMM related optimization or something. – Kayaman Oct 31 '17 at 08:02
  • I did say this was a _General answer_ ... I did not mention this specific case. But if the class need to be updated for any reason, concurrency, immutability, ... this would be simpler to do this in `getArray` instead of every method using the array. So I would guess a bit of paranoia from the dev doing this method – AxelH Oct 31 '17 at 08:06
  • @AxelH the class is part of `java.util.concurrent` by Doug Lea. There's most likely a very good reason for it. – Kayaman Oct 31 '17 at 09:29
  • @Kayaman The duplicate doesn't really answer the question, operating directly on the field would've achieved the exact same thing. The explained "voodoo" has nothing to do with calling `getArray` and/or `setArray`. – Oleg Oct 31 '17 at 10:20
  • @Kayaman Maybe, maybe not, in any case it's not the same "voodoo". The answer to this question should be based on the duplicate, claiming that it is a duplicate of that question is misleading. – Oleg Oct 31 '17 at 10:53
  • 1
    See https://stackoverflow.com/questions/28772539/why-setarray-method-call-required-in-copyonwritearraylist for discussion about the related `setArray()` method. It's memory model voodoo, probably related to compiler/JIT/other optimization, unfortunately Doug Lea didn't comment on the code for the specific reason. However, there's definitely a purpose for them and it's not the same as just accessing the array directly. Stuart Marks in the linked question is one of the people (with Brian Goetz and others) who have worked on the Java Memory Model and related things. – Kayaman Oct 31 '17 at 10:57
  • @Kayaman Yes, I saw it, it's the wrong duplicate. Stuart explains the `set()` method, there is absolutely no discussion about `setArray` vs direct access in that answer. The purpose is most certainly not definite, it might have been done purely for convenience and clarity reasons. Based on the jmm there is no difference. – Oleg Oct 31 '17 at 11:10
  • I wasn't referring to you. I was commenting generally after I reopened the question. There is definitely a reason for it, since the comment above the array says `The array, accessed only via getArray/setArray.` indicating a relevance. – Kayaman Oct 31 '17 at 11:10

1 Answers1

1

"Why did they design it that way" questions are always a matter of conjecture. This one is as well ... unless the code's author (Doug Lea) were to explain his thinking to us.

However, I think that the primary reason is stylistic.

  • The array variable is declares as private.

  • The getArray method is declared as package private with the comment:

    // Gets the array. Non-private so as to also be accessible 
    // from CopyOnWriteArraySet class. 
    

If there wasn't a method, it would be necessary to declare the array variable itself as package private. I think (and I suspect that Doug also thinks) that a package private getter is much better than a package private field. (For all the standard reasons.) And if the getter and setter exist, it is reasonable to use them.

The related question (Why setArray() method call required in CopyOnWriteArrayList) explains why there are calls to setArray in apparently unnecessary places. But that's an orthogonal issue.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216