Mike Schilling wrote:
[me]
I suppose, but what would a catch block for NullCastException do?
That's where null-case code would go.
The advantage of doing the null-checking in that way would be that the
nullable/non-nullable distinction could be handled in the language (so that
javac "knew" whether a given reference could possibly be null) without
requiring relatively intricate extensions to the flow analysis that it is
required to perform. I.e. without special syntax like "ifnull" or sematic
additions like requiring the compiler to recognise "if (aRev == null)" as a
special case. Admittedly, it's kinda kludgy....
You've lost me, because I thought that's what I was proposing
If
you're asking if I think it's a good idea, yes, though I can't see adding
it to Java now without insuperable compatibility issues.
I didn't know if you were thinking of it as something desirable (if not
necessarily feasible now), or were more interested in it as a design
experiment. (I'm more in the latter camp, myself -- though I wouldn't say that
it's a bad idea /if/ you allow that static declarative typing is a good idea in
the first place.)
Perhaps it could be introduced in a non-breaking way. First off, it would
obviously have to be a compile-time only thing, like generics. Secondly it
would have to "play nicely" with older third party libraries that didn't use
it. Ideally, it would not prohibit new code from running on older JVMs though
that is presumably not a necessary condition (compare Sun's implementation of
generics which also refuses to target older editions of the platform).
Lets say that there's a new flag that can be added to classes along the lines
of "strictfp". If a class is flagged with "strictnull" (or perhaps a special
flag is passed to the compiler which causes it to assume strictnull by default
for the target classes), then it will interpret the declaration
<sometype> var;
as meaning the non-nullable variant of <sometype>. Special syntax is required
to mark specific types as nullable/not-nullable. I rather like the idea of
using a generics-style syntax myself with Nullable<sometype> being the nullable
equivalent of a given type (which might already have been nullable), and
NotNullable<sometype> as the not nullable equivalent of a given type (which
might already have been not-nullable). The "strictnull" flag is then telling
the compiler whether to assume Nullable<> or NotNullable<> by default for
declarations in that class.
Some way of expressing tell-tests is then needed, as discussed earlier. One
problem with using the NullCastException approach is that that would require an
new checkable exception in the standard hierarchy. That would make it
impossible to run new code on an old JVM. Also methods that allowed
NullCastExeption to leak could not normally be called /from/ old code, since
they wouldn't have the relevant handlers. That could be seen as an advantage,
though.
Lastly, we need some way of recording what type-discipline is used for a given
class in the classfile. But that's pretty trivial since it can be handled as
an upward compatible extension to the format in much the same way as generics
are. The nullable/not-nullable qualifiers on type references would be "erased"
in a similar way to generics, but would be recorded in a separate part of the
classfile, where newer compilers would see it and could compile accordingly.
Older compilers would ignore it (as would the JVM itself) and so the underlying
semantics would not change, so NullPointerExceptions would still be possible as
far as the underling implementation knows.
Hmm... I'm starting to think that it's doable...
-- chris