L-type, Q-type and class mirrors
Remi Forax
forax at univ-mlv.fr
Wed Jan 12 11:45:18 UTC 2022
Hi all,
i want to propose a way to reconcile builtin primitive types and primitive classes in the B1/B2/B3 world.
Let's take a detour, and try to answer to the question, how do we do reflection on method with Q-types ?
Given that reflection is using the class java.lang.Class, it means that we need a class that represents a L-type and a class that represent a Q-type.
The class that represents a Q-type does not have to be a 'real' class, the same way int.class (Integer.TYPE) is not a real class,
it's a mirror class that represent 'I' in the method signature, same with void.class (Void.TYPE) represent 'V'.
So the class that represents a Q-type is a mirror class synthesized by the VM at runtime.
Given that it is synthesized, i believe it should be only accessible using a method of java.lang.Class,
by example
Complex.class.mirrorType() // the name "mirror" is perhaps not the best
Once we agree about that, we can push a little further and see how we can have only one unified kind of primitive class.
If we want to be able to have an ArrayList of int, we need either to see int as a Q-type or Integer as a Q-type.
The later is more attractive because it means that at runtime we can see a ArrayList<QjInteger;> as an ArrayList<LInteger;>
so call a method of an existing API using ArrayList<Integer> with the more compact ArrayList<QjInteger;>.
So java.lang.Integer is a primitive class.
But it's not a true primitive class because
- in a method descriptor because of backward compatibility, it has to be a Ljava/lang/Integer;
- inside the '<' '>' of a generics, we need a way to express a Q-type.
I propose to introduce a new kind of primitive class, the builtin primitive class, that
- use L-type in signature
- are eagerly loaded by the VM (this is already the case) thus does not need to appear in the attribute Preload.
- this is more controversial, inside a generics, int is translated by the compiler to Qjava/lang/Integer; + usual boxing/unboxing operations
so ArrayList<int> is a specialized generics using the class miror corresponding to Qjava/lang/Integer; as argument.
In practice, only the wrapper types, Byte, Short, Integer, etc, can be declared as builtin primitive
(by example, the compiler can restrict the use of builtin to java.base or java.lang).
Rémi
More information about the valhalla-spec-observers
mailing list