(Continuing this thread from relevant discussion on [1])
Discussing the following RFE:
https://bugs.openjdk.java.net/browse/JDK-8256341
Also (as mentioned offline), while it's possible with the current API
to provide an `Object[]` as class data, and then load elements of
that array into CP entries using downstream condys (e.g. by creating
an array access var handle and then using that), I think it would be
good to add a `getArrayElement` BSM for doing that to
`ConstantBootstraps` to make this (seemingly) common case easier
(maybe also a `getField` for loading instance fields). This would
help to address the case where multiple live constants need to be
injected.
I am uncomfortable with adding `ConstantBootstraps::getArrayElement`
because an array is modifiable and _not_ true constant. A final
instance field can be modified via reflection and therefore it's not
trusted as a constant either.
I guess it would be similar to doing something like:
private static final Object[] arr = getArray();
private static final Object o = arr[0];
Setting `arr[0] = new Object();` would not affect `o` after it has been
initialized. The difference being that a constant for the array element
would be resolved (more) lazily, so it would be possible to resolve the
array, then modify it, and then resolve the constant that loads the
element, which would see the updated value as well.
However, we can already store an array in the constant pool today, and
modify it if we want, even though, as you say, it is mutable. In that
sense getArrayElement doesn't introduce anything new.
Mutating the array is probably a bad idea though, so maybe we want to
push users away from using arrays? To prevent inadvertent modification,
maybe an immutable `List` should be used in place of a plain array. In
that case, would you feel differently about added a `getListElement`
BSM, that gets an element from an (immutable) List instead?
Another idea is to rely on records, since they can not be mutated with
reflection at all. i.e. we add a getRecordComponent BSM instead, so a
class data Object can be a record, and then the BSM can be used to
extract individual components. Though, the record class would probably
have to be reflectively accessible from the point where the constant is
resolved as well.
WDYT?
Jorn
[1] : https://github.com/openjdk/jdk/pull/1171