JVM does not match JVMS regarding array component types?
Anton W. Haubner
anton.haubner at outlook.de
Wed Apr 13 09:12:00 UTC 2022
Hi!
I am not sure if this is the right place to ask these questions. At
first glance, the "jls-jvms-spec-comments" mailing list looks more
appropriate but its description says that that list "is solely a drop
box for reports".
Therefore, if I am out-of-place here, please direct me to the
appropriate mailing list.
My question is about the behaviour of the JVM which seemingly does not
match the JVMS specification when it comes to lazy-linking and empty arrays.
I noticed that regarding lazy-linking strategies and resolution, the
JVMS states that if an array type is resolved whose element type is a
reference type, then
"a symbolic reference to the class or interface representing the element type is resolved [...] recursively." [1]
More specifically, the `anewarray` instruction requires the resolution
of the component type when executed [2].
However, while inspecting programs with the JDI, I observed that when
creating an empty array, the component type of the array is actually not
loaded.
You can observe this as follows:
1. Compile the following program with `javac -g`:
```
class Test { }
public class ArrayTest {
public static void main(String[] args) {
var x = new Test[] {};
}
}
```
2. Executing `javap -v ArrayTest` will confirm that when stopping the
program on line 6, `anewarray` must have been executed.
3. Run the following commands in `jdb`:
stop at ArrayTest:6
run ArrayTest
class Test
4. It will say "Test is not a valid id or class name.", i.e. the class
"Test" has not been loaded, even though it should have been because it
is the component type of Test[] for which an instance has been created.
5. If you change line 5 to "var x = new Test[] {new Test()};" jdb will
actually return information about "Test", that is, the class is loaded.
From these observations I conclude, that the component type of an array
type is not loaded, if only empty instances of the array type are created.
I wonder, why this does not violate the specification of the JVMS at [1]
and [2]
(I am working with Java 11, so so far I tested this only for OpenJDK 11)
[1] Section 5.4.3.1, Java Virtual Machine Specification, Java 11:
https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-5.html#jvms-5.4.3.1
[2]
https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html#jvms-6.5.anewarray
More information about the discuss
mailing list