I’ve been reading this post, which eventually led me to this JDK7 proposal. In the blog post itself, a lot of the comments were about whether the hash sign (#) or a more IntelliJ style @NotNull annotation should be used. One even suggested allowing for annotations defined in a certain package (say, java.lang.annotations) to be used with the @ sign in certain cases (such as parameter or method definition), making them “virtual keywords”. I’m not sure how this works for everything, but it’s an interesting idea.
In any case, Stephen’s reluctance from using @NotNull is seen both in his own comments:
Annotations are, according to the Sun guys, not to be used for language features. I agree.
And his proposition:
Alternate proposals suggest adding an @NotNull attribute to fields and parameters. Whilst this tackles the same problem area, it suffers from being verbose and intrusive. It is also the wrong device (an annotation) for fixing what is a language level missing piece (full handling and control of nulls). Finally, the annotation does not tackle the code clarity issues addressed in section II of this proposal.
I don’t tend to agree. First, it’s clear that the “Sun guys” are not so sure about this themselves, see JSR-305 tackling a very similar problem using annotations. Second, I’m less afraid of the verbosity of the annotation, especially if we’ll take JSR-305’s @DefaultNotNull or @DefaultNullable into account. Which is something that Stephen doesn’t address at all: What if I prefer to have non-null parameters and variables as the default? Unfortunately, this can’t be made the default - existing codebase will break if this was made the default. However, if we consider existing codebase as having the @DefaultNullable annotation, new classes could be written with a @DefaultNotNull annotation and there you go!
On the other hand, the @NotNull and @Nullable alternative doesn’t really deal with old codebase, since it doesn’t have a way to convert between a @Nullable (which might be the default for old codebase) and @NotNull (which is what I actually expect the code to return, in cases such as toString).
For a more concrete example, let’s compare the two options in a probable code written with the new null-safe feature:
class Person {
private #List<#Person> children = ...;
public #String getNameOfChildAtIndex(int childIndex) {
// check for validity
if (childIndex >= children.size()) ... ;
// list is old Java
#Person child = (#) children.get(childIndex);
// toString is old Java, too.
return (#) child.toString();
}
}
On the other hand:
@DefaultNotNull
class Person {
List<Person> children = ...;
// both are automatically set to @NotNull
String getNameOfChildAtIndex(int childIndex) {
// check for validity
if (childIndex >= children.size()) ... ;
Person child = children.get(childIndex);
// old code-base is not checked,
// and might cause an error.
return child.toString();
}
}
There are other differences that make it harder to decide which is better. It is my opinion that the annotations’ solution is the better one, and we should be seeing more annotations adding Java features as time goes by, such as the @Override and @Deprecated annotations for methods.

September 23rd, 2007 at 4:49 am
By the way, just for clarity…
JSR 305 defines a standard set of annotations and is not dependent on Java 7. If JSR 308 (which does change the Java language, so would need to be part of a new Java version) expanded the set of places annotations could be used, JSR 305 could be used in more places. These two JSRs are frequently mentioned together and their relationship is not always clear.
Thanks for the inital link too - I don’t have that on my Java 7 page so I’ll add it.
September 23rd, 2007 at 6:26 am
Yes, you’re correct. The two do often come together, since I didn’t have an example showing JSR-308 features, I didn’t add a note about it. Thanks!
September 24th, 2007 at 5:26 pm
[…] Chaotic Java has been on a tear the last few days with several interesting Java language posts. First up, he blogged about a couple proposals to indicate whether nulls are accepted, and then took on sending events using closures, and C# delegates vs Java closures. All good and interesting stuff worthy of your attention. […]
September 24th, 2007 at 9:45 pm
Since the majority of methods are designed for not accepting nulls, either by intent or by accident,
I’d actually suggest having non-nullable as default and (re)using the null keyword for this, and thus avoiding adding new syntax to the language.
For a method accepting null in its second argument, and possibly returning a null, the method signature would be as such:
public null Object getData(String key, null String classifier);
These null checks are applicable both for static analysis by the compiler, and also as runtime checks inserted by the compiler.
The latter could then selectively be disabled in the same way as assertions could be:
java -disablenullchecks:com.misbehaving… -enablenullchecks:org.wellbehaving…
September 24th, 2007 at 10:36 pm
Asgeir: The problem with enabling non-nullable as default is certainly not with the syntax (which I still think should be an annotation, as it doesn’t change the syntax for declaring a method).
It’s with what you do with all the old codebase: In your suggestion, all the old codebase will be deemed as if it’s never returning null - which is obviously not true.
September 25th, 2007 at 9:18 am
The problem with NotNull on a variable declaration is that it doesn’t go far enough and causes verbose definitions. Consider a RealNum class where null has no meaning, i.e. it doesn’t make sense to have a null RealNum:
class RealNum {
RealNum max( @NotNull RealNum other ) { … }
RealNum times( @NotNull RealNum other ) { … }
…
}
@NotNull RealNum x1 = …;
A better solution is to declare a class NotNull, which means that no instance of the class can be null and therefore further NotNull annotations aren’t needed, e.g.:
@NotNull class RealNum {
RealNum max( RealNum other ) { … }
RealNum times( RealNum other ) { … }
…
}
RealNum x1 = …;
September 25th, 2007 at 9:23 am
Howard: You’re not showing a problem; there is no problem with placing NotNull on variable declarations as in a lot of cases (most, I would assume) this is a preferable choice (such as placing a @NotNull on a String parameter instead of on the String declaration).
Your proposal is interesting though as it might be useful for logically-internal classes where the default should always be for them to be not-null, no matter where they are used.
December 5th, 2007 at 1:41 am
Another solution might be to have three levels. @NotNull, @Nullable, , with the default being or set with @Default*…
Legacy code would have “unknown”, and unchecked assignments would generate warnings, where as unchecked nullable assignments @NotNull references would be errors.
Also, perhaps not specifying nullability (either with Default, or otherwise) would generate a warning.
December 5th, 2007 at 7:07 am
@Daniel: Wouldn’t that make all your code generate warnings and errors? I don’t see the java compiler generate warnings for me today for not using the @Override annotation everywhere, even though it would be extremely useful if I did.
This has to be an opt-in option in order to allow it to integrate smoothly into the developers’ mind, in my humble opinion..
January 31st, 2008 at 10:33 am
Most methods do not accept null parameter, it only make sense to explicitly mark a parameter as not nullable rather than nullable.
And I think compiler should not check this kind of thing, I mean we must balance ourselves between static and dynamic. Clearly having compiler to check for null is way too static. Compiler should do basic type checking and obvious mistakes like not returning value in non void methods.
I would prefer parameter to have simple annotation like @NotNull in JDK so that people know a method’s parameter null constraint without having to read javadoc.
I think java should focus on getting important things right rather than adding more and more features. It’s time for Java 2.0, break away from old Java 1.x backward compatibility burden. Please put generic in compiled classes, I want true generic! And where is property!? I hate the idea of generating getters and setters in Eclipse, clearly we need property notation here. Please remove all deprecated methods, badly designed classes.
March 17th, 2008 at 10:10 pm
Hi folks,
I clearly think, not-null constraints should be done by the compiler. And I also think it should be new keyword (variable/parameter modifier) instead of annotations, because it would be the easiest and most obvious way to write.
(Annotations are just a way for assigning metadata which normally has no direct influence on the actual code).
Let’s go back to the time where generics were introduced: would you really have done them via annotations ? (I hope NOT).
I’ve written some bit about this issue here:
http://j.metux.de/index.php?option=com_content&task=view&id=53
March 26th, 2008 at 7:37 am
Enrico: Since I cannot answer in your post, I will answer it here.
What you change sounds too extreme: why change the way variables are stored when all you want to make sure is that the compiler tell you if you’re using null value on a not-null variable?
Regarding the annotation, this is exactly it: generics are intended to be something that affects the way the class is compiled, and hopefully when the backwards compatibility features (i.e. erasure) are removed we’ll have something that works on the bytecode-level. However, not-null and nullable are compiler-time features, just like “@Override”; they’re there in order to generate compiler warnings/errors, but not to change the way the JVM might behave.