4 ms·
This is exactly why java needs frozen arrays [1]. The safe thing to do is freeze the array before doing anything with it. Then, you can rely on COW to copy to
by cogman10 3y ago
This is exactly why java needs frozen arrays [1].
The safe thing to do is freeze the array before doing anything with it. Then, you can rely on COW to copy to the array if someone is modifying it concurrently with you reading it. In the general case, you'd have fast string creation and in the tricky case you simply pay the clone cost as a penalty for being dumb.
[1] https://openjdk.org/jeps/8261007#:~:text=How%20do%20I%20use%20a%20frozen%20array%3F%201,an%20array%20is%20frozen%20or%20modifiable.%20More%20items https://openjdk.org/jeps/8261007#:~:text=How%20do%20I%20use%...
- malfist 3y agoJava does have immutable collections. It's just not an explicit type. Lots of common ways to instantiate arrays (i.e. Arrays.asList) generate immutable lists
- thfuran 3y agoThat's instantiating a List, not an array.
- tialaramex 3y agoAs you would expect in a vaguely modern language, Java's "List" interface is typically backed by a growable array as the type ArrayList. Only people who have no idea about caches would think List should necessarily be some sort of Linked List type. You would use Collections.unmodifiableList to make it unmodifiable.
- cowsandmilk 3y agoCollections.unmodifiableList doesn’t prevent anyone who has a reference to the original List (or the array behind it) from modifying the List. Calling that in the constructor would not help.
- thfuran 3y agoYes, ArrayLists are array-backed, but Arrays.asList instantiates a List and does not instantiate an array.
- tialaramex 3y agoAs I explained, List is an interface. You can't instantiate it, values are instances of types not interfaces. All that return type is telling you is, surprise, asList promises what you're getting implements the List interface. See if you can guess how you can implement the List interface using an Array. Still struggling, here's the one line of a typical implementation: return new Arrays.ArrayList(a);
- thfuran 3y agoYou should at least try to be correct if you're going to be so insufferable about it.
- cowsandmilk 3y agoArrays.asList doesn’t generate an immutable list, prevent writes to the array, or prevent modifying the array via the List interface. https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Arrays.html#asList(T https://docs.oracle.com/en/java/javase/17/docs/api/java.base......)
- layer8 3y agoThis doesn’t help when the parameter is one of the collection interfaces, or CharSequence, or the like. You always need to defensively copy their contents first to “freeze“ their values.
- wjholden 3y agoI would love to have this in Java, hopefully this JEP makes it!
- cogman10 3y agoAs would I. There are a ton of places where the JVM is defensively copying arrays. It often comes up (for me in my work) as a performance problem. A real common example of this is `Enum#values`. Ideally (IMO) this applies some aggressive COW operations. So perhaps internal to the enum you have a frozen array of the values and for "values()" you return something like `VALUES.unfreeze()` which points to a transparent unfrozen array. On a write action, you'd copy the array but in the general case you'd simply read from the frozen array until someone does something dumb. You could take it a step further and simply expose the `values` field or add a new "frozenValues" method to not break existing code. In either case, you'd end up with faster performance because the JVM isn't copying the internal array needlessly.