Thoughts on Array Initialization in JavaONE 2025
Remi Forax
forax at univ-mlv.fr
Sun Jul 27 16:08:04 UTC 2025
> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "david Grajales" <david.1993grajales at gmail.com>, "amber-dev"
> <amber-dev at openjdk.org>
> Sent: Saturday, July 26, 2025 11:48:49 PM
> Subject: Re: Thoughts on Array Initialization in JavaONE 2025
> All of the points you raise that "arrays are not the abstraction you are looking
> for" are absolutely true -- and well understood. The goal of improving array
> creation is not to help arrays win market share away from collections.
> But there is a reason that the language has arrays, and that reason hasn't gone
> away. Arrays are the bottom brick on which the tower of better data structures
> are built. You can't have ArrayList or HashMap without arrays. Arrays are part
> of the language for a reason. As we improve the language, sometimes arrays have
> to improve with it. (For example, if you have a non-implicitly-constructible
> value class NVA (one who has no valid default value), and someone wants to
> create an array of NVA![n], allowing the existing "zero the memory" array
> creation expression to create it would undermine the integrity of the runtime
> by exposing objects that are not in a valid state as determined by their
> constructor. So we can't allow that, which means we have to provide something
> else.)
> If we hadn't found the need to improve other aspects of initialization, we
> probably wouldn't have bothered to improve array initialization. But because we
> are improving initialization more broadly, we have to do the whole job. Not
> being able to create interesting arrays linguistically would forever look like
> a weird omission.
> Your suggestion -- "why not just" not improve array creation linguistically, and
> shunt any sort of exotic array creation to a privileged API -- leaves the user
> with little explanation for why the tower stands up. The bottom brick is not
> there, instead replaced by some sort of magic that seems to hold up the brick
> above it. While we expect relatively few programmers to program with arrays
> (ideally, just the guy who maintains ArrayList and HashMap, and the like), we
> should provide linguistic mechanisms for properly using core linguistic
> building blocks.
> I can imagine three implicit lines of thought for why you think such a low-level
> mechanism should be performed by a privileged library rather than a language
> feature:
> - The easier we make it to use, the more people will use it, and you would like
> fewer people to use it (as would we.) A scary-looking library will scare away
> more people than a pretty-looking language feature.
> - Language features are expensive, more expensive than libraries, so by shunting
> this to a library, we preserve resources to focus on more important things.
> - Array initialization appears to be competing for resources with features like
> collection literals, and you'd rather have the latter, so suggesting that we
> skip the former seems like it would bring the latter more quickly.
> These are appealing-sounding arguments, but they don't point to either usability
> wins or project-management wins. Arrays are the right tool for some jobs.
> Collections are the right tool for others (most others.) But the way to
> encourage people to use the right tool is not to make the other tools harder to
> use. (We too would like to have linguistic support for creating sets, lists,
> maps, etc, but that feature is not competing with arrays, its waiting for
> something else.) Nor is the cost of a privileged array-construction API
> significantly cheaper than a language feature.
I always flip-flop between thinking that arrays are redeemable and losing all hope about them :)
I think that the solution to our problem is to use value classes, after all, a value class allows abstraction without the runtime cost, right, so why not eating our own dog food ?
Why not using array wrapped into a value class that implements the List interface ?
By example, here is a List that allows only to access to an element of the List only if it has been initialized first (using a watermark),
value class WatermarkedList<E> implements List<E> {
E[] array;
int watermark;
// private constructor + static method
WatermarkedList<E> append(E element) {
array[watermark] = element;
return new WatermarkedList<>(array, watermark + 1);
}
E get(int index) {
Objects.checkIndex(index, watermark);
return array[index];
}
int size() { return watermark; }
WatermarkedList<E> copyOf(int newCapacity) { ... }
...
}
Here the array can be initialized with zeroes (using a "JDK restricted" method) and a WatermarkedList is still safe to be used with element that are NVA.
I think the JDK can define few of those lightweight Lists that can be used as primitive by anyone wanting to implement more complex data structures (ArrayList, HashMap, etc).
> Cheers,
> -Brian
regards,
Rémi
> On 7/26/2025 5:03 PM, david Grajales wrote:
>> Dear Amber developers,
>> I recently watched the JavaONE 2025 session titled “A New Model for Java Object
>> Initialization” and was particularly intrigued by the proposed improvements to
>> array initialization.
>> [ https://www.youtube.com/watch?v=XtvR4kqK8lo |
>> https://www.youtube.com/watch?v=XtvR4kqK8lo ]
>> I strongly agree that Java needs better mechanisms for initializing data
>> structures in a concise, expressive, and stricter manner—similar in spirit to
>> Python’s list comprehensions and aligned with Strict initialization, required
>> for Valhalla. Such constructs can help avoid subtle bugs and the presence of
>> unintended null values. However, I remain skeptical about the decision to focus
>> this new model exclusively around arrays.
>> As has been discussed over the past few months, arrays are not ideal as a
>> default abstraction, especially for students or in enterprise applications.
>> Arrays are a low-level construct with several limitations:
>> *
>> They do not integrate well with generics.
>> *
>> They are of fixed size.
>> *
>> They lack methods and flexibility.
>> *
>> They are syntactically and semantically inconsistent with the rest of the Java
>> Collections Framework.
>> In many ways, arrays are a legacy feature inherited from C/C++—much like the
>> original switch statement—that carry forward certain limitations that Java has
>> otherwise worked hard to overcome.
>> Given these issues, Why not just create an small API that facilitates the
>> creation of the most used data structures with strict initialization?
>> For example:
>> void main(){
>> // toArray
>> var array = StrictCollections.toArray(String.class, 5, i -> "Item-" + i);
>> IO.println("Array: " + Arrays.toString(array));
>> // toList
>> var list = StrictCollections.toList(5, i -> "List-" + i);
>> IO.println("List: " + list);
>> // toSet
>> var set = StrictCollections.toSet(5, i -> "Set-" + (i % 3));
>> IO.println("Set: " + set);
>> var map = StrictCollections.toMap(
>> 5,
>> i -> "Key-" + i,
>> i -> i * 100
>> );
>> IO.println("Map: " + map);
>> }
>> public static class StrictCollections {
>> public static <T> T[] toArray(Class<T> clazz, int size, IntFunction<T> function)
>> {
>> @SuppressWarnings("unchecked")
>> T[] array = (T[]) Array.newInstance(clazz, size); // This could be a frozen
>> array once these are ready
>> for (int i = 0; i < size; i++) {
>> array[i] = function.apply(i);
>> }
>> return array;
>> }
>> public static <T> ArrayList<T> toList(int size, IntFunction<T> function) {
>> var list = new ArrayList<T>(size);
>> for (int i = 0; i < size; i++) {
>> list.add(function.apply(i));
>> }
>> return list;
>> }
>> public static <T> HashSet<T> toSet(int size, IntFunction<T> function) {
>> List<T> list = new ArrayList<>(size);
>> for (int i = 0; i < size; i++) {
>> list.add(function.apply(i));
>> }
>> return new HashSet<>(list);
>> }
>> public static <K, V> HashMap<K, V> toMap(int size, IntFunction<K> kFunction,
>> IntFunction<V> vFunction) {
>> HashMap<K, V> map = new HashMap<>(size);
>> for (int i = 0; i < size; i++) {
>> map.put(kFunction.apply(i), vFunction.apply(i));
>> }
>> return map;
>> }
>> }
>> While this is admittedly a rough sketch developed in just a few minutes, I
>> believe a similar—much more thoroughly designed—approach could provide much
>> greater flexibility with far less complexity than introducing a dedicated
>> array-specific feature. It would also extend naturally to a broader range of
>> use cases --Such as being able to be combined with the Stream API in a much
>> more ergonomic way--. Furthermore, as value classes and parametric JVM start to
>> make it into the language and the JVM, the advantages of arrays and primitive
>> types will diminish further. In that context, arrays will become even less
>> compelling in the future.
>> If Java is to introduce a safe, expressive, and idiomatic strict initialization
>> literal for data structures, I would argue it should primarily support List ,
>> Set , and Map —especially Map , which remains one of the least ergonomic
>> structures to initialize in the language today, particularly when compared to
>> alternatives in Dart, Python, or even JavaScript objects. Data structures that
>> are much more used.
>> Thank you so much for all your work and always yours
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20250727/a77ff07a/attachment-0001.htm>
More information about the amber-dev
mailing list