@Nullable and @NotNull

In past I made a couple of unsuccessful half-hearted runs at getting
@Nullable and @NotNull to work. 

Today I gritted my teeth and I think I have got them working.  I wrote
an easy-to-follow step-by-step essay on how to make them work.

See http://mindprod.com/jgloss/atnullable.html

Please inform me of any errors or suggestions for improvement.
--
Roedy Green Canadian Mind Products
http://mindprod.com
Capitalism has spurred the competition that makes CPUs faster and
faster each year, but the focus on money makes software manufacturers
do some peculiar things like deliberately leaving bugs and deficiencies
in the software so they can soak the customers for upgrades later.
Whether software is easy to use, or never loses data, when the company
has a near monopoly, is almost irrelevant to profits, and therefore
ignored. The manufacturer focuses on cheap gimicks like dancing paper
clips to dazzle naive first-time buyers. The needs of existing
experienced users are almost irrelevant. I see software rental as the
best remedy.

6 comments

On Sat, 05 Nov 2011 10:29:59 -0700, Roedy Green
<see_website@mindprod.com.invalid> wrote, quoted or indirectly quoted
someone who said :

>In past I made a couple of unsuccessful half-hearted runs at getting
>@Nullable and @NotNull to work. 
>
>Today I gritted my teeth and I think I have got them working.  I wrote
>an easy-to-follow step-by-step essay on how to make them work.
>
>See http://mindprod.com/jgloss/atnullable.html
>
>Please inform me of any errors or suggestions for improvement.

Reorganise imports was discarding my imports

import org.jetbrains.annotations.NotNull; 
import org.jetbrains.annotations.Nullable;

I told the Auto-import dialolog to exclude these two classes.  Is the
best way to handle the problem?
--
Roedy Green Canadian Mind Products
http://mindprod.com
Capitalism has spurred the competition that makes CPUs faster and
faster each year, but the focus on money makes software manufacturers
do some peculiar things like deliberately leaving bugs and deficiencies
in the software so they can soak the customers for upgrades later.
Whether software is easy to use, or never loses data, when the company
has a near monopoly, is almost irrelevant to profits, and therefore
ignored. The manufacturer focuses on cheap gimicks like dancing paper
clips to dazzle naive first-time buyers. The needs of existing
experienced users are almost irrelevant. I see software rental as the
best remedy.

0

Guest wrote:

Please inform me of any errors or suggestions for improvement.
--
Roedy Green Canadian Mind Products


Hello Roedy,

I did notice a few things...

The 11 steps you list for adding the annotations to your project can be replaced with:

  1. Type the @Nullable or @NotNull annotation
  2. Hit alt+enter (quick fix) and select "Add 'annotations.jar' to classpath"  (or "Add maven dependency" if it's a maven project)
  3. Click OK to the dialog and continue working.

screenshot.png

The annotations force you to add specific code for null checking, possible an
assert or if ( var != null ) perhaps overly conservatively.

I would disagree with this statement on a few different levels.

  1. The annotations do not force you to do anything. I can annotate a  method parameter as @NotNull and then call it with a null value. The  code will compile and run (possibly throwing a NullPointerExcecption).  IDEA will warn me that I am calling a method annotated as  @NotNull with a null value (or with a possibly null value). But it does  not "force" me to do anything.
  2. That statement has an air about it that using the @NotNull  annotation makes it so you need to do extra work and put in extra code.  But adding null checks for method parameters when calling methods that  do not guarantee null safety has always been a necessary step in  development. But without the annotation, you had to read the JavaDoc to  determine null safety. And the IDE could not warn you about.
  3. Finally, if I am passing in a value to one method that requires  @NotNull parameters, and that value was obtained by another method whose  return value is marked @NotNull no null check is necessary. In that way  it saves you coding and reduces the need for "overly conservative"  defensive programming.

You can mark parameters and returns (but not variables) as either @Nullable . . . or @NotNull

Actually,  you can mark variables, both local variables and instance variables,  i.e. feilds, If you bring up the ajavadoc (CTRL+Q) for the annotation,  or look at the source code, you will see that the annotations have a  target of: {ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE}

You describe returns by putting the @Nullable/@NotNull before everything in the method declaration, e.g. before the public.You describe parameters by putting the @Nullable/@NotNull before everything in the parameter e.g. before the final.


To  me, those sentences make it sound as if the placement of the annotation  where described is a requirement. Placing annotations at the start of a  method declaration and prior to parameter modifiers is a coding  convention. It is the most common coding convention; but still a  convention. It is not a compiler syntax requirement of the Java  language. The following will compile and run just fine:
    public static @NotNull String myMethod(final @NotNull String xyz)
So you may want to change those sentences to something like "The common convention is to put the...".

The annotations are proprietary to IntelliJ. They have offered them to Oracle to include in standard Java, but Oracle has not accepted them.

JetBrains  can comment on this statement... but I'm not sure if "proprietary" is a  correct choice of words since the annotations are actually open source,  licensed under the Apache License, Version 2.0. Also, you can configure  IDEA to use and recognize other annotations. By default, since version  10, IDEA will recognize, in addition to its own annotations,  the javax.annotation.Nullable and javax.annotation.NonNullable annotations from the JSR-305 specification and its implementations, and the @Nullable and @NonNull annotations from the FindBugs project. You can also configure IDEA to recognize any other annotations: File > Settings > Project Settings > Inspections > Probable Bugs > @NotNull/@Nullable problems > Click the "Configure annotations" button

This will only apply to your 1.6 and 1.7 targets.

Annotations were added to Java in version 1.5. (See the "preface to the third edition" and section 9.7 "Annotations" of the JSL, third edition.)  So their use applies to Java 1.5 as well.

Strange as it sounds, it is also possible to store your annotations separately from the source code, though the IntelliJ IDE (Integrated Development Environment) will display them as if they were embedded.

I  guess I do not understand this statement. Any library you use -- log4j,  SLF4J, XStream, Spring, mysql-connector-j, commons-lang, junit, etc,  etc, -- are stored separately from the source code. And many of them use  annotation. The JSR-305 jar is nothing but annotation. So sotring the  IDEA annotations separately from the source code does not sound strange  to me at all. And I doubt it would to any other Java developer. Perhaps I  am misunderstanding what the statement is saying.

To make the annotations available to your JDK (Java Development Kit) used by IntelliJ to compile your code (as distinct from the JRE (Java Runtime Environment) it uses to run the IDE), or to let ANT compile outside IntelliJ, you will need to install annotations.jar in your own various ext directories.

I'm  not sure why you recommend adding these annotations to the JDK's  extension directory. If you compile through IDEA, it will automatically  add the jar to the classpath argument of the javac command  since it is a module library. And if compiling via the command line,  you simple need to reference the jar manually via the classpath  argument, as you would any third party library you are using. You  certainly don't put every any any third party library you use in the  JDK's extensions directory. So I'm not sure why these annotations would  be any different.

At this point all will work fine, except that if you reorganize your imports the following lines will disappear:

// Disappearing imports for @NotNull and @Nullable
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable

What you have to do now is configure the auto-import function to ignore these imports:

AND

Guest wrote:

Reorganise imports was discarding my imports

import org.jetbrains.annotations.NotNull;  
import org.jetbrains.annotations.Nullable;

I told the Auto-import dialolog to exclude these two classes.  Is the
best way to handle the problem?

Not sure I follow these comments at all. I've never seen IDEA make an import statement of a class or annotation that is in use disappear. If a imported class of annotation is not in use a class, IDEA will remove it from the list of imports when running an import optimization. But if they are in use, IDEA will not remove them. Based on your settings, IDEA may combine them to a wild character import of import org.jetbrains.annotations.*; Or it might move them in the order they were listed in. But it  certainly will not make them disappear (again, as long as they are in use).

Configuring the auto-import  has nothing to do with the import optimization / reorganization. By  adding these values to the auto-import exclude list, you will be forced to type the import statements manually  each time you go to use the annotations. With auto-import, IDEA will automatically add  them as soon as you use them. If for some reason you are not happy with  how IDEA is organizing those imports (the order, the use of wild  character, etc.) those settings are File > Settings > Code Style > Java > Imports tab. Not the auto-import options.

I do not know of any way to tell IDEA to not remove certain specific imports when they are not in use. That would be contradictory to the concept of optimizing imports. So if you do not want unused imports to be removed, the answer would be to not run the import optimization tool. But if an import is not in use, I do not see why you would want or need it in your imports. Configuring IDEA to ignore them in auto-import actually makes the problem worse. If you are not using them at the moment abd you optimize your imports, the unused import statement is removed. When you do go to use them, IDEA will not automatically add them and you will no have to go back up to your imports and add them manually.

0

On Mon, 07 Nov 2011 07:12:41 MSK, Mark Vedder <no_reply@jetbrains.com>
wrote, quoted or indirectly quoted someone who said :

>The 11 steps you list for adding the annotations to your project can be replaced with:
>1. Type the @Nullable or @NotNull annotation
>2. Hit alt+enter (quick fix) and select "Add 'annotations.jar' to classpath"  (or "Add maven dependency" if it's a maven project)
>3. Click OK to the dialog and continue working.

Image:screenshot.png

>The annotations force you to add specific code for null checking, possible an
>assert or if ( var != null ) perhaps overly conservatively.
>I would disagree with this statement on a few different levels.
>1. The annotations do not force you to do anything. I can annotate a  method parameter as @NotNull and then call it with a null value. The  code will compile and run (possibly throwing a NullPointerExcecption).  IDEA will warn me that I am calling a method annotated as  @NotNull with a null value (or with a possibly null value). But it does  not "force" me to do anything.

Thank you.

I have incorporated what you said.  Does your approach make the
imports unnecessary? protected from reorganise import?
--
Roedy Green Canadian Mind Products
http://mindprod.com
Capitalism has spurred the competition that makes CPUs faster and
faster each year, but the focus on money makes software manufacturers
do some peculiar things like deliberately leaving bugs and deficiencies
in the software so they can soak the customers for upgrades later.
Whether software is easy to use, or never loses data, when the company
has a near monopoly, is almost irrelevant to profits, and therefore
ignored. The manufacturer focuses on cheap gimicks like dancing paper
clips to dazzle naive first-time buyers. The needs of existing
experienced users are almost irrelevant. I see software rental as the
best remedy.

0

My website is aimed at the newbie, not advanced people like you.  That
explains my comment that suggests the reader might be surprised to
discover it is possible to keep annotations about code outside the
code itself.

You also wondered why I talk about dealing with these annotations
outside of IntelliJ.

Long before I encountered IntelliJ, I was composing distributable zips
combining source  in ASM,Forth/C/C++/Java, documentation, jars,
Javadoc, images ... using complicated generated ANT scripts.

I have only used IntelliJ for debugging.  I export the source from
IntelliJ and run scripts in ANT, BTM and BAT. The point of much of my
code is teaching novices.  So I want everything I distribute to be
fairly easy for other people to experiment with and rebuild without
IntelliJ.

It was just a few days ago I wrote my first @Nullable.  I found
IntelliJ's documentation difficult, so I thought the world needed
something simpler. The catch is, I still don't know what I am doing.
My general strategy is to write what I think is true, then I find
people like you are willing to spend huge amounts of time correcting
me, where they would be much less likely to explain in such detail
otherwise.

When this works, I end up with accessible, informal, explanations that
are also accurate and complete.

--
Roedy Green Canadian Mind Products
http://mindprod.com
Capitalism has spurred the competition that makes CPUs faster and
faster each year, but the focus on money makes software manufacturers
do some peculiar things like deliberately leaving bugs and deficiencies
in the software so they can soak the customers for upgrades later.
Whether software is easy to use, or never loses data, when the company
has a near monopoly, is almost irrelevant to profits, and therefore
ignored. The manufacturer focuses on cheap gimicks like dancing paper
clips to dazzle naive first-time buyers. The needs of existing
experienced users are almost irrelevant. I see software rental as the
best remedy.

0

On Mon, 07 Nov 2011 07:12:41 MSK, Mark Vedder <no_reply@jetbrains.com>
wrote, quoted or indirectly quoted someone who said :

>
>Configuring the auto-import  has nothing to do with the import optimization / reorganization.
By  adding these values to the auto-import exclude list, you will be
forced to type the import statements manually  each time you go to
use the annotations. With auto-import, IDEA will automatically add 
them as soon as you use them. If for some reason you are not happy
with  how IDEA is organizing those imports (the order, the use of
wild  character, etc.) those settings are +File > Settings > Code
Style > Java > Imports tab.+ Not the auto-import options.
>
>I do not know of any way to tell IDEA to not remove certain specific imports when they are not in use.
That would be contradictory to the concept of optimizing imports. So
if you do not want unused imports to be removed, the answer would be
to not run the import optimization tool. But if an import is not in
use, I do not see why you would want or need it in your imports.
Configuring IDEA to ignore them in auto-import actually makes the
problem worse. If you are not using them at the moment abd you
optimize your imports, the unused import statement is removed. When
you do go to use them, IDEA will not automatically add them and you
will no have to go back up to your imports and add them manually.



What was happening before I did that kludge was I would use reformat
with optimise imports.  Then the fool thing would remove my imports
even when I WAS using @Nullable and @NotNull.  I have no complaint
with it removing them if I am not using them.

Perhaps your way of enabling annotations does something that makes
this wrongful delete not happen.
--
Roedy Green Canadian Mind Products
http://mindprod.com
Capitalism has spurred the competition that makes CPUs faster and
faster each year, but the focus on money makes software manufacturers
do some peculiar things like deliberately leaving bugs and deficiencies
in the software so they can soak the customers for upgrades later.
Whether software is easy to use, or never loses data, when the company
has a near monopoly, is almost irrelevant to profits, and therefore
ignored. The manufacturer focuses on cheap gimicks like dancing paper
clips to dazzle naive first-time buyers. The needs of existing
experienced users are almost irrelevant. I see software rental as the
best remedy.

0

On Mon, 07 Nov 2011 07:12:41 MSK, Mark Vedder <no_reply@jetbrains.com>
wrote, quoted or indirectly quoted someone who said :

Is there any way to do something with Javac.exe outside of IntelliJ to
get warning messages if the @Nullable @NotNull constraints are
violated?

Do you have to do something to Javac.exe outside of IntelliJ so that
it will not choke on the imports and the annotations, even if it does
nothing with them?

In other words, what is  the purpose of the redist/annotations.jar

IntelliJ has its own slightly older JVM. My understanding is it uses
this for running the IDE and for doing dynamic syntax checking as you
type. But when you hit BUILD, it uses one of your Javac.exe's
(possibly even a 64 bit one). Is that correct?

What checks that the constraints are not violated:  the IntelliJ  IDE,
Javac amplified with annotation.jar9 ffrom  IntelliJ, both?


--
Roedy Green Canadian Mind Products
http://mindprod.com
Capitalism has spurred the competition that makes CPUs faster and
faster each year, but the focus on money makes software manufacturers
do some peculiar things like deliberately leaving bugs and deficiencies
in the software so they can soak the customers for upgrades later.
Whether software is easy to use, or never loses data, when the company
has a near monopoly, is almost irrelevant to profits, and therefore
ignored. The manufacturer focuses on cheap gimicks like dancing paper
clips to dazzle naive first-time buyers. The needs of existing
experienced users are almost irrelevant. I see software rental as the
best remedy.

0

Please sign in to leave a comment.