javaintellij-ideajava-21

Where does the inferred @NotNull come from?


I've been looking at Function.java from Microsoft\jdk-17.0.11.9-hotspot\lib\src.zip!\java.base\java\util\function\Function.java

It appears like this in IntelliJ IDEA 2024 : enter image description here

I couldn't help but notice that there's an automated (inferred) @NotNull added by IntelliJ in front of Function<...> in the method prototype.

Where does the @NotNull come from? In other words : What does this class have that my own classes don't have? (None of my classes make IntelliJ add @NotNull spontaneously even when the context makes it clear).

Note: I looked at annotation @FunctionalInterface 's inner workings but could not find a direct link between how it works and this @NotNull. Maybe it's there, I just don't see it.


Solution

  • You seem to be making the assumption that your code should work exactly like standard library code, and that's not the case.

    IntelliJ has special handling baked in for certain library code. In this case, it comes from an XML file, but there are also some other code paths and certain hardcoded things. IntelliJ calls these "external annotations", and you can add your own too.

    <item name='java.util.function.Function java.util.function.Function&lt;V,R&gt; compose(java.util.function.Function&lt;? super V,? extends T&gt;)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val name="pure" val="true"/>
        </annotation>
        <annotation name='org.jetbrains.annotations.NotNull'/>
    </item>
    

    Intuitively, we can see that that default implementation will never return null. It either throws or returns a function.

    The reason IntelliJ doesn't infer the annotation, even if you copy and paste the same code to a new file, is that just because the default implementation doesn't return null, that doesn't imply that implementers are not allowed to. For all IntelliJ knows, implementers are allowed to return null. It needs this extra data to give the method a stronger contract than it can infer.