Java most wanted: Non-null variables

D

Dimitri Maziuk

David Wahler sez:
I'm not sure I'm following you. Only the variables that are declared as
non-nullable would need to be checked.

Are you sure about that? -- you're compiling the *caller* and checking
that it does not pass a null to
public foo( @NotNull x )
declared elsewhere.

....
If the database table may contain nulls, the result would obviously
need to be stored in a nullable variable. But there are many situations
in which a null reference should never happen, and in those cases it
makes sense to enforce this constraint statically

Really? I happen to know that column i in my table is declared NOT NULL,
so null reference from ResultSet.getX( i ) "should never happen". Would
that be one of "those cases" where I declare
public foo( @NotNull x )
for use with
foo( ResultSet.getX( i ) )
so as to "enforce this constraint statically"? Or is this the case
where x "obviously needs to be a nullable variable"?

Dima
 
P

P.Hill

Dimitri said:
And it still won't work unless you make sure *no* variable
can ever be set to null: via function return, declaration
without initialization, RMI, RPC, socket read, etc. Oh, and
database fetch: did I mention all database types will have
to be NOT NULL?

It won't work unless every way in and out, many of which you
have mentioned (but many of them reduce down to whether a
return value can be null), has been declared to either possibly
be null or never be null, so that the much simpler analysis
might be done. The proposal was to make those declarations
and box the problem in.

Each of your above examples would have to declare their return values
as nullable in their respective library implementations, if your
statement is shown to be correct, but for example, all InputStream.read
methods return something.

I believe that any such method of marking arguments and return values
would then lead to the requirement to provide a way for someone to say
"you can't tell from the code, but this API is guaranteed to never
return null." A possibly dubious feature.

I maintain that getting all APIs to declare which possibility
exists for their return values is an impossible maintenance
hurdle, regardless whether the analysis could be done when
presented with sufficient information.

It *might* be a feature for a new language, but it is an
insurmountable impossibility for an existing language even
if it is shown to be possible and useful.

-Paul
 
C

Chris Uppal

Thomas said:
Consider constructors. They can call (possibly virtual) methods before
they are constructed. You then have an object loose with null non-null
fields.

ArrayLists. You might never store nulls, and declare it as such, but the
backing array is going to be full of nulls. How do you decipher that?
You can still get nulls from it, if it's used in a non-thread safe manner.

I think that these issues could be resolved, if not quite perfectly. The basic
idea would be that the programmer could tell the compiler that <such-and-such>
was /intended/ not be non-null (which the compiler would just believe), or that
<such-and-such> was /required/ to be non-null (which the compiler would verify
by static analysis where possible and by a runtime check otherwise). The
latter case would be directly analogous to casts in the current type system;
the former has no direct analogue.

The case of ArrayLists is interesting. One option that the programmer would
have would be to tell the compiler that it could assume that no read of the
array would return a null. The compiler (perhaps naively ;-) believing that,
would then allow the get(int) operation to declare that it never returned a
null. Hence get() could be implemented without a run-time null-check (if
that's desired). So far so good. But, as you say, there are threading issues
too. I don't think that it's /necessary/ for the type system to be able to
handle such cases; it would be nice if it could, but if it can't then that
doesn't mean that the feature is useless.

Similarly, the fields could be declared to be non-null, and that declaration
might be false if the programmer abuses constructors. Not nice, but at least
/most/ accesses are subject to static confirmation. And -- if we want the
extra safety -- we can use the stronger form of the assertion at the
point-of-use of the field. (Compare the current situation with final
variables, which can -- despite appearances -- be seen in their uninitialised
state in some circumstances).

I'm not claiming that the change to the language would actually pay for itself,
but I don't think we can dismiss it as valueless even though the issues you
raise do dilute that value.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top