Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

Goodbye, checkNotNull

 Precondition checking like null-checking is very important element for program, but sometimes it becomes boring because it's a defensive technique and far apart from our purpose -- hacking.

public MyClass(String name) {
	if (name == null) {
		throw new IllegalArgumentException();
	} = name;

 Yes, I know the Guava library makes it easy. Preconditions class is my favorite, and we can use it to simplify checkings. For example, we can code precondition checking and assignment etc. in same line.

public MyClass(String name) { = checkNotNull(name);

 But I still have some problems. At 1st, users of this class have to read this implementation to know 'name should be non-null value'. Do you want to write '@param name should not be null' or '@throw NullPointerException if name == null' in your Javadoc? I don't! I've already written it in the code.
 しかしまだいくつか解決したい問題が残っています。1つめは、クラスの実装を読んでもらわないとnameがnullであってはならないということが伝わらないことです。Javadoc'@param name nullは渡さないで!'とか'@throw NullPointerException nameがnullの場合に投げる'とか書きたくはありません。コードの中の情報と重複しています。

 At 2nd, we cannot select its exception. I know that throwing NullPointerException at null checking is traditional way for Java, but the IllegalArgumentException is more meaningful option*1 I think. We can avoid this problem to use checkArgument(name != null) instead of for a while.
 2つめは、NullPointerException以外の例外を投げられないということです。ヌルチェックに引っかかった場合はNPEを投げるのが伝統的とは言え、より例外として意味を持っているIllegalArgumentExceptionを投げたくなる*2ときもあります。まぁcheckArgument(name != null)と書けばこの問題はひとまず回避できますが……。

 To solve these problems, I created a maven plugin and pushed it to the GitHub. With this plugin, we can rewrite it like below.

public MyClass(@Nonnull String name) { = name;

 The @Nonnull is one of annotations defined in JSR 305. This maven plugin injects precondition checking to compiled class files. @Nullable, @Nonnegative and @MatchesPattern are ready to inject.
 この@NonnullはJSR 305で定義されているアノテーションの1つです。このMavenプラグインは@Nonnullや@Nullable、@Nonnegativeに@MatchesPatternといったJSR 305のアノテーションをもとに事前条件確認のコードをクラスファイルに埋め込みます。

 These annotations are annotated by @Documented, so they are documented in Javadoc by default. And tools like FindBugs will tell 'don't pass null' to users. 1st problem is solved by them. This plugin has a feature to change exception to throw, so our 2nd problem is solved too.
 This plugin is not mainstream as how to use JSR 305 annotations, but is very useful for me. I'm using this for some projects and brushing up. I'm happy if you try to use and like it. Happy hacking!
 これはJSR 305の使い方としては異端だと思いますが、今のところ便利に使えています。今後も自分のプロジェクトで使いながら改善していくつもりです。よろしければお試しいただければ幸いです。

*1:NPE means 'Oops! It's null!' but IAE means 'Your argument is wrong'.