Bug 492591 - Map.get(<K>) gives erroneous "Null comparison always yields false" warning on @Nullable return
Summary: Map.get(<K>) gives erroneous "Null comparison always yields false" warning on...
Status: RESOLVED DUPLICATE of bug 331651
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.5.2   Edit
Hardware: PC Windows 8
: P3 normal (vote)
Target Milestone: 4.5 M6   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-27 14:43 EDT by Adrian Price CLA
Modified: 2016-04-28 09:37 EDT (History)
1 user (show)

See Also:


Attachments
Test case (524 bytes, text/plain)
2016-04-27 14:43 EDT, Adrian Price CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Adrian Price CLA 2016-04-27 14:43:46 EDT
Created attachment 261315 [details]
Test case

Obviously, the Map.get(<K>) return value may be null (since the map may not contain the key) but if you assign the return value to an @Nullable variable then test that value for null the compiler issues the erroneous warnings: "Null comparison always yields false", along with "Dead code".

Illustrative case attached.
Comment 1 Stephan Herrmann CLA 2016-04-27 14:54:00 EDT
Have you seen https://www.eclipse.org/eclipse/news/4.5/jdt.php#Annotations ?

Scroll down to "Annotate command" and you'll see exactly your example of Map.get().

Explanation: due to @NonNullByDefault, the declaration "Map<String, String> map" actually instantiates the type parameter 'V' as '@NonNull String', hence Map.get(..) returns '@NonNull String'.

To fix this mark the return of get(..) as '@Nullable V' - how: use external annotations.

See also http://help.eclipse.org/topic/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm

HTH

*** This bug has been marked as a duplicate of bug 331651 ***
Comment 2 Adrian Price CLA 2016-04-28 04:38:11 EDT
(In reply to Stephan Herrmann from comment #1)

Many thanks for your detailed explanation Stephan.

I had seen the documentation on external annotations and it interests me greatly. However, web searches did not reveal the existence of any pre-built 'jdk-1.8.eea' file, and preparing an accurate and complete one manually looks daunting and time consuming. Are you aware of any downloadable eaa files, repositories or community efforts to collect such artefacts?

Anyhow, perhaps I misunderstand something - it was my belief that Null Type analysis treats 3rd party binaries as 'nullability unknown'. On this basis I had assumed that one could obtain an accurate analysis by placing, as in my example, a @Nullable type annotation on a variable assigned from a 'nullability unknown' return value, then guarding derefencing code with a null check. In my example, the erroneous warning shows that the compiler is ignoring the @Nullable annotation and incorrectly inferring that the value is @NonNull, which is clearly incorrect if 3rd party libraries are supposedly being treated as 'nullability unknown'.
Comment 3 Stephan Herrmann CLA 2016-04-28 09:37:48 EDT
(In reply to Adrian Price from comment #2)
> I had seen the documentation on external annotations and it interests me
> greatly. However, web searches did not reveal the existence of any pre-built
> 'jdk-1.8.eea' file, and preparing an accurate and complete one manually
> looks daunting and time consuming. Are you aware of any downloadable eaa
> files, repositories or community efforts to collect such artefacts?

These topics will hopefully be addressed via bug 479536.
Some early ideas had been captured some time ago in https://wiki.eclipse.org/JDT_Core/Null_Analysis/External_Annotations#Collecting_annotations


> Anyhow, perhaps I misunderstand something - it was my belief that Null Type
> analysis treats 3rd party binaries as 'nullability unknown'.

For normal types this holds true. 
Unfortunately, for type variables we have a conflict, which led to the recent changes documented in https://www.eclipse.org/eclipse/news/4.6/M6/#null-analysis-generics
Please scroll to item (2) and see an additional warning that has been introduced for this case.