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