Automatic @NotNull/@Nullable/@Contract inference in IntelliJ IDEA 14

Posted on by

Java annotations are awesome and helpful, but you need to add them by hand. Well, not anymore, because IntelliJ IDEA will do that for you in some quite important cases.

Jars in your dependencies are stuffed with methods and sometimes it may be difficult to tell whether you can pass null there without blowing things up, or whether you should be ready to get null as a method result.

If you’re lucky, the documentation will specify that, if not, you have to read the source code, or even the decompiled output, which is not always as easy as you’d like it to be. There are, of course, NotNull/Nullable annotations available in various frameworks, but not everybody uses them. JDK doesn’t, for example. IntelliJ IDEA supports external annotations, but they also don’t cover most of existing jars.

Well, this is what happens now. IntelliJ IDEA will look carefully at SDK and libraries bytecode and will infer these annotations automatically so that they can later be used to analyze source code to spot places where you overlooked null. You can see these inferred annotations in italic in the editor gutter.

Contrary to the already available Infer Nullity feature, this one works with bytecode and is completely automatic: the results are just there in the editor, and you don’t have to do anything to make that happen.

Of course, the logic behind this feature is not as simple as “if a parameter is immediately dereferenced, then it’s @NotNull”. There’s science at work behind the curtains that does a lot more, for example, recursively processes delegating method calls.

For methods with a more complex behavior, as you probably know, we have the method contracts. These are now inferred, too. Why is this important? Well, suppose you’re using Apache Commons StringUtils and have such warnings in your code:

Earlier IntelliJ IDEA had no clue that code execution wouldn’t even reach the “startsWith” call if the url is null because it didn’t look inside StringUtils.isEmpty. You could of course remove those yellow warnings in extractPrefix by looking inside isEmpty yourself and adding a contract “null -> true”, but that’s so boring! That’s exactly a job for computer, not you, and now IntelliJ IDEA does it automatically, looking at byte and source code.

Get the latest preview build and see how this works for you. We are eager to hear your feedback, be it bugs, usability issues or suggestions about more annotations to infer.