How to get NPE warning caused by functions returning null?

Background

Sometimes functions return null in some cases, and yet the one who uses them did not know about it, so NPE is inevitable.

For example (and just an example to show what I'm talking about):

public class Test { public static void main(final String[] args) { final int t=0; System.out.println("result:"+foo(t).toString()); // no warning here... } public static String foo(final int t) { if(t>0) return "positive"; else return null; } } 

Problem

Eclipse does not warn about this, and does not even have it in the settings.

It can detect such problems only when no functions are involved (see my editing below).

Not only that, but I can't find an annotation that says the return value can be null. I think the opposite is true.

What i tried

So, I thought that since Eclipse does not have some checks (and this is good), I could use alternative static code analysis tools like FindBugs and CodePro Analytix . Both could not find such errors.

I tried to contact both projects, but have not received an answer yet. for CodePro Iโ€™m not even sure that I did it right ... Actually, I think this project was discontinued (last update in 2010 ...).

Question

Is there any tool that can help avoid such errors?


EDIT: since many people think that this is solvable by simply changing the code, think about working in a huge team where some people might forget about it (everyone could be wrong). Or maybe you are even working on a project that uses the SDK (which may even be closed source), which may return null in some cases, but it is not documented because the creator of the SDK forgot about it.

This can happen, no matter how good you are as a programmer.

What I ask is a way to overcome this by allowing eclipse help. he should be able to warn me, at least in the basic examples that I wrote here.

Eclipse should be able to do such checks, just like it can warn me about this example:

 int t=0; --t; String s="s"; if(t<0) s=null; System.out.println(s.toString()); // here you will get a warning 

This can be detected when you enable it in the Eclipse settings:

 Java-> Compiler-> Errors/Warning-> Potential null pointer access 

I like Eclipse because it has a lot of great warnings and errors that can help avoid errors, but what I wrote above is not detected by it and not even with the tools that I talked about.

Many errors are hard to find, and no one is the perfect programmer who is not mistaken. Even if you know a lot, you are not protected from other people's mistakes. People may not even find what is wrong with the base code (see here , here or just here to see how well you can find the errors yourself). That's why there are tools that can help you.

+6
source share
3 answers

Consider using @Nullable and @NonNull in your code. This may partially solve your problem.

UPDATE: usage example copied from http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-using_null_annotations.htm

 @NonNull String getString(String maybeString) { if (maybeString != null) return maybeString; // the above null check is required else return "<n/a>"; } void caller(String s) { System.out.println(getString(s).toUpperCase()); // no null check required } 

UPDATE: case with @Nullable

 public @Nullable String getMessage() { return System.currentTimeMillis() % 2 != 0 ? "That odd..." : null; } public void showCase() { String msg = getMessage(); if (msg.isEmpty()) { //- Here it yields about possible null access //... } } 

UPDATE: settings for Null Analysis in my environment:

Eclipse setting for null analysis

Actual error message from Eclipse:

enter image description here

UPDATE: you need to include JAR with Eclipse annotation in the build path. Move the mouse over the @NonNull or @Nullable , which cannot be compiled (as shown in the image), and select "Copy library with default annotations by default" to build the path -

enter image description here

A new JAR should appear in the Package Explorer, and the compiler should be able to see it. Then move the cursor to the annotation and press Ctrl + Space - Eclipse should find the correct import (note that you can see two different packages in the list: select one from the JDT) - and select it. It should work.

+4
source

Write unit tests for your code:

 @Test public void testFooWithZero() { try{ Test tester = new Test(); assertEquals("Expect string returned", "positive", tester.foo(0)); catch(NullPointerException npe) { fail("Threw NPE"); } } 

Not only do they describe your expected behavior (usually better than the lazily written Javadoc), it ensures that your code does what you expect.

Write tests for positive and negative scenarios, and you are golden.

Static code analysis certainly has its advantages, but it has its limitations. A common case will be how you protect against the return value of get(Object) from a HashMap or similar collection. SCA does not know what data is in the collection at runtime. You will not be able to comment on code from major Java packages or from third parties.

Unit tests should be used in an additional way and improve the quality of your code. See this question for several advantages and reasons why you should consider it:

Is unit testing worth the effort?

+1
source

Methods have two methods of signaling this kind of "failure." Return null or exception, which is usually indicated in javadoc. Returning null is not an error per se since, for example, HashMap.get(key) returns null if there is no value associated with the key. If you exclude the HashMap exception, it will be a bad choice. On the other hand, some JPA methods throw an exception if an entity is not found (for example, requesting a unique entity that is expected to exist).

Imagine the number of warnings you would have if every time you used the HashMap , eclipse would say "be careful, it can return null."

So, to summarize: it would not be very useful to warn about this in real life, since you will start to ignore warnings due to clutter.

0
source

All Articles