-
Bug
-
Resolution: Fixed
-
P4
-
None
-
generic
-
generic
Where statically discernible, should javac disallow null being cast into a value type ?
This topic is still being discussed.
In http://mail.openjdk.java.net/pipermail/valhalla-dev/2018-February/003801.html, it is stated:
The current design allows null references for value types, as long as they are not stored
in a container (field or array) declared as flattenable. This is a significant change from
previous design. So, casting null to a value class type is now legal.
In http://mail.openjdk.java.net/pipermail/valhalla-dev/2018-February/003803.html it is stated:
There might be an option here: Maybe we could get away with having checkcast
throw NPE if the target class is a value type. After all, the checkcast instruction resolves
its class operand. Remember that we *must* allow polluting nulls in fields which
are not explicitly marked as flat, but *only* because of binary compatibility requirements.
We *do not* allow polluting nulls to be stored into arrays, because arrays *must*
resolve their element types before the first array is constructed. I think we could
put checkcast into either of these two categories: Allowing polluting nulls for
compatibility, or forbidding them (throwing NPE).
Hmm… The more aggressive choice (throwing NPE on checkcast) would make would
prevent instances of generic code (such as List<DoubleComplex>) from accepting
nulls:
List<DoubleComplex> xs = new ArrayList<>();
xs.add(null); // to NPE or not to NPE?
This is not really a JVM question, but a language question: Should
the above code throw NPE if freshly recompiled? Yes, probably.
What if it is inside a legacy classfile, and is not freshly recompiled?
It would break if it threw NPE. This argues for two slightly different
versions of checkcast. Argh: An option turns into a two-sided mandate.
The checkcast might need a flat-bit. (Stay away, you Q-types.)
Or the checkcast could throw NPE only in newer classfile versions.
These considerations also apply to Class::cast.
This topic is still being discussed.
In http://mail.openjdk.java.net/pipermail/valhalla-dev/2018-February/003801.html, it is stated:
The current design allows null references for value types, as long as they are not stored
in a container (field or array) declared as flattenable. This is a significant change from
previous design. So, casting null to a value class type is now legal.
In http://mail.openjdk.java.net/pipermail/valhalla-dev/2018-February/003803.html it is stated:
There might be an option here: Maybe we could get away with having checkcast
throw NPE if the target class is a value type. After all, the checkcast instruction resolves
its class operand. Remember that we *must* allow polluting nulls in fields which
are not explicitly marked as flat, but *only* because of binary compatibility requirements.
We *do not* allow polluting nulls to be stored into arrays, because arrays *must*
resolve their element types before the first array is constructed. I think we could
put checkcast into either of these two categories: Allowing polluting nulls for
compatibility, or forbidding them (throwing NPE).
Hmm… The more aggressive choice (throwing NPE on checkcast) would make would
prevent instances of generic code (such as List<DoubleComplex>) from accepting
nulls:
List<DoubleComplex> xs = new ArrayList<>();
xs.add(null); // to NPE or not to NPE?
This is not really a JVM question, but a language question: Should
the above code throw NPE if freshly recompiled? Yes, probably.
What if it is inside a legacy classfile, and is not freshly recompiled?
It would break if it threw NPE. This argues for two slightly different
versions of checkcast. Argh: An option turns into a two-sided mandate.
The checkcast might need a flat-bit. (Stay away, you Q-types.)
Or the checkcast could throw NPE only in newer classfile versions.
These considerations also apply to Class::cast.