| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html lang="en"> |
| <head> |
| <meta name="copyright" content="Copyright (c) GK Software AG and others 2014, 2015. This page is made available under license. For full details see the LEGAL in the documentation book that contains this page." > |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <meta http-equiv="Content-Style-Type" content="text/css"> |
| <link rel="stylesheet" href="../book.css" charset="ISO-8859-1" type="text/css"> |
| <title>Using null type annotations</title> |
| </head> |
| <body> |
| <h1> Using null type annotations </h1> |
| <p> |
| Starting with Java 8, null annotations can be used in a new and more powerful way, |
| because the new concept of "type annotations" (JSR 308) supports the use of |
| annotations as an extension to the type system. |
| </p> |
| <p> |
| Technically, this is determined by two new elements in |
| the enum <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html" |
| ><code>java.lang.annotation.ElementType</code></a>: <code>TYPE_USE</code> and |
| <code>TYPE_PARAMETER</code>. Notably, when saying <code>@Target(ElementType.TYPE_USE)</code> |
| the annotation thus marked can be attached basically to all usages of a type. |
| </p> |
| <p> |
| By interpreting null annotations as part of the type system we interpret each |
| class or interface <code>Cn</code> in the system as introducing two distinct types: |
| "<code>@NonNull Cn</code>" and "<code>@Nullable Cn</code>". |
| The former type contains all instances of <code>Cn</code> whereas the latter type |
| additionally contains the value <code>null</code>. |
| This implies that <code>@NonNull Cn</code> is a subtype of <code>@Nullable Cn</code> |
| with all regular consequences regarding assignability. |
| So ideally for every value in a program we will know if it can be null |
| (and must be checked before dereference) or not. |
| The un-annotated type will be considered a legacy type just like raw types are legacy |
| types since the introduction of generics: a way for interfacing with old code, |
| to be flagged with warnings about unchecked conversions. |
| If we systematically avoid such legacy types, then the compiler can rigorously |
| flag <em>every</em> unsafe usage. |
| </p> |
| <p> |
| In order to achieve completeness of null analysis, checks regarding null type annotations |
| have been integrated with all type checking tasks of the compiler (active if null annotations |
| are enabled). |
| </p> |
| <p> |
| Users <em>migrating</em> from null annotations in previous versions to Java-8-style |
| null type annotations are advised to check the section about <a href="#compatibility">compatibility</a>. |
| </p> |
| <p> |
| Note, that the actual qualified names of null type annotations are |
| <a href="../reference/preferences/java/compiler/ref-preferences-errors-warnings.htm#null_annotation_names">configurable</a>, |
| but by default the ones shown here are used (from the package <code>org.eclipse.jdt.annotation</code>). |
| When using 3rd party null annotation types, please ensure that those are properly defined using at least a <code>@Target</code> |
| meta annotation, because otherwise the compiler can not distinguish between declaration annotations (Java 5) |
| and type annotations (Java 8). Furthermore, some <a href="#compatibility_semantics">details of <code>@NonNullByDefault</code></a> |
| are not supported when using 3rd party annotation types. |
| </p> |
| |
| |
| <h2 id="generics">Generics</h2> |
| Perhaps the main advantage of type annotations for null analysis is the ability to annotate |
| the parameters and arguments of generic classes and interfaces. |
| Programmers only <em>using</em> generic classes may directly skip to the section on |
| <a href="#typeArguments">type arguments</a> but designers of generic classes should |
| take the time to understand the different implications of annotating these elements: |
| <ul> |
| <li><a href="#typeParameters">type parameters</a></li> |
| <li><a href="#typeVariables">type variables</a></li> |
| <li><a href="#typeArguments">type arguments</a></li> |
| </ul> |
| <h3 id="typeParameters">Type parameters</h3> |
| <p> |
| A generic class, interface or method may <em>declare</em> one or more type parameters. |
| Technically these are declarations, and hence it was a mere oversight that these cannot |
| be annotated in Java 5. |
| In Java 8 an annotation can declare <code>@Target(ElementType.TYPE_PARAMETER)</code> |
| to be applicable in this position. JDT's null type annotations |
| <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/NonNull.html"><code>@NonNull</code></a> and |
| <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/Nullable.html"><code>@Nullable</code></a> |
| are declared with |
| <code>@Target({ TYPE_USE })</code>, which includes usage on type parameter declarations. |
| </p> |
| <p> |
| With respect to null type annotations, each type parameter can be specified at one |
| of these levels: |
| </p> |
| <dl> |
| <dt><strong>unconstrained</strong></dt> |
| <dd>the type parameter does not impose any nullness-constraints on the arguments that |
| a client my substitute for the type parameter.</dd> |
| <dt><strong>constrained by an upper bound</strong></dt> |
| <dd>the type parameter has an <code>extends</code> clause that specifies |
| minimal nullness-requirements on type arguments provided by clients</dd> |
| <dt><strong>exactly specified</strong></dt> |
| <dd>the type parameter restricts usage to types of exactly one particular nullness</dd> |
| </dl> |
| <p> |
| Constraining a type parameter via an <strong>upper bound</strong> relies on the fact that each type |
| '<code>@NonNull Cn</code>' is a subtype of the corresponding type '<code>@Nullable Cn</code>'. |
| Hence, a <code>@Nullable</code> upper bound does not impose any restriction, whereas a |
| <code>@NonNull</code> upper bound prohibits the substitution by a <code>@Nullable</code> |
| type argument: |
| <pre> // declarations: |
| class C0<T0 extends @Nullable Object> {} // meaningless, no constraint imposed |
| class C1<T1 extends @NonNull Object> {} |
| ... |
| // usage: |
| C1<@NonNull String> c1String; // legal |
| C1<@Nullable String> c1String; // illegal |
| </pre> |
| <p> |
| For <strong>exact specification</strong> a null annotation may be attached to the type parameter |
| declaration itself, which is interpreted as defining both an upper and a lower bound. |
| In other words, only types with the exact same null type annotation are legal as type arguments: |
| </p> |
| <pre> // declaration: |
| class C2<@Nullable T2> {} |
| ... |
| // usage: |
| C2<@NonNull String> c2String; // illegal |
| C2<@Nullable String> c2String; // legal |
| </pre> |
| <p> |
| Given the asymmetry, that in Java a type parameter may declare only upper bounds but |
| no lower bounds, the following three styles can be recommended: |
| <ul> |
| <li>Use a <code>@NonNull</code> upper bound for constraining type arguments to nonnull types.</li> |
| <li>Directly specify a type parameter as <code>@Nullable</code> for constraining type arguments to nullable types.</li> |
| <li>Use an unconstrained type parameter to support type arguments of either nullness.</li> |
| </ul> |
| <h3 id="typeVariables">Type variables</h3> |
| <p> |
| Within the scope of a generic declaration (class, interface or method), the name of a |
| type parameter can be used as a <em>type variable</em>, i.e., a placeholder for a type |
| that is not known at this point. |
| </p> |
| <p> |
| A type variable will typically be used without (further) null annotations, which implies |
| that the annotations from the type parameter declaration will apply as detailed below. |
| In some situations, however, it is useful to annotate an individual use of a type variable. |
| As an example consider the library method <code>java.util.Map.get(Object)</code>, |
| which should actually be annotated like this: |
| </p> |
| <pre> @Nullable V get(Object key)</pre> |
| <p> |
| By this declaration we would indicate that the return type is <strong>the nullable variant |
| of whatever type V may represent</strong>. In other words, a null annotation on the use |
| of a type variable <em>overrides</em> any other null information that would otherwise |
| apply to this type. In particular any null annotation on the corresponding type parameter |
| declaration (or its bound) is overridden by a null annotation in this position. |
| </p> |
| <p> |
| On the other hand, when using a type variable without immediate null annotations the following rules apply |
| depending on the declaration of the corresponding type parameter: |
| </p> |
| <p> |
| A type variable corresponding to a type parameter with a <strong><code>@NonNull</code> upper bound</strong> |
| denotes a type that is <em>known to be nonnull</em>. |
| </p> |
| <pre> class C1<T1 extends @NonNull Number> { |
| int consume(T1 t) { |
| return t.intValue(); // OK since T1 is known to be nonnull |
| } |
| T1 provide() { |
| return null; // NOT OK since T1 requires nonnull |
| } |
| } |
| </pre> |
| <p> |
| A type variable corresponding to a type parameter <strong>specified as <code>@Nullable</code></strong> |
| denotes a type that is <em>known to be nullable</em>. |
| </p> |
| <pre> class C2<@Nullable T2 extends Number> { |
| int consume(T2 t) { |
| return t.intValue(); // NOT OK since T2 is known to be nullable |
| } |
| T2 provide() { |
| return null; // OK: returning null is legal |
| } |
| } |
| </pre> |
| <p id="pessimistic_analysis"> |
| A type variable corresponding to an <strong>unconstrained</strong> type parameter requires <strong>pessimistic |
| checking</strong> in order to guarantee safety with all legal substitutions: this type can |
| neither be assumed to be nullable nor nonnull. |
| </p> |
| <pre> class C<T extends Number> { |
| int consume(T t) { |
| return t.intValue(); // NOT OK since T could be nullable |
| } |
| T provide() { |
| return null; // NOT OK since T could require nonnull |
| } |
| } |
| </pre> |
| <p> |
| The last point may look surprising at first, but please see that an unconstrained type parameter |
| implies that we may not assume anything about the nullness of the type represented by |
| the corresponding type variable. Even more: we must actively support nullable <em>and</em> |
| nonnull types. On the other hand this simply extends the existing rule that the only |
| type being compatible with an unbounded type variable is the type variable itself. |
| To explain this situation in the context of null analysis, the compiler will raise the |
| following error against the return in <code>provide()</code>: |
| </p> |
| <blockquote> |
| Null type mismatch (type annotations): 'null' is not compatible to the free type variable 'T' |
| </blockquote> |
| <p>The severity of problems detected by this pessimistic analysis is controlled by a dedicated <a href="../reference/preferences/java/compiler/ref-preferences-errors-warnings.htm#pessimistic_analysis">preference option</a>. |
| <p> |
| By enforcing this defensive strategy regarding unconstrained type parameters we obtain the benefit |
| of allowing clients to freely choose the rules for a particular generic instantiation, |
| as will be shown next. |
| </p> |
| <h3 id="typeArguments">Type arguments</h3> |
| <p> |
| When instantiating a generic type or when invoking a generic method, the constraints put |
| forward by the type parameter must be observed. Hence, when a provider of a generic type or method |
| specified the required nullness, this must be obeyed and the compiler will flag any violations. |
| </p> |
| <p> |
| When, on the other hand, a type parameter does not impose any restrictions, a client may |
| freely choose the nullness of his type arguments: |
| <pre> |
| int processWithoutNulls (@NonNull List<<strong>@NonNull Integer</strong>> ints) { |
| int result = 0; |
| for (int i = 0; i < ints.size(); i++) { |
| Integer element = ints.get(i); |
| result += element.intValue(); // OK: list element is known to be nonnull |
| ints.set(i, null); // NOT OK: list does not accept null value |
| } |
| return result; |
| } |
| int processWithNulls (@NonNull List<<strong>@Nullable Integer</strong>> ints) { |
| int result = 0; |
| for (int i = 0; i < ints.size(); i++) { |
| Integer element = ints.get(i); |
| result += element.intValue(); // NOT OK: list element can be null |
| ints.set(i, null); // OK: list accepts null value |
| } |
| return result; |
| } |
| </pre> |
| <h3 id="substitution">Substitution</h3> |
| <p> |
| The intention behind combining null type annotations with generics is to propagate a constraint defined for a type argument |
| into all occurrences of the corresponding type variable. For example, if you declare a variable of type <code>List<@NonNull String></code> |
| and invoke any method from <code>List<T></code> on this variable, all method signatures will see type <code>T</code> substituted by <code>@NonNull String</code>. |
| This is how inserting a <code>null</code> value into this list is made impossible, and allows to safely regard elements extracted from this list as nonnull. |
| The previous section gave examples of exactly this idea. |
| </p> |
| <p> |
| Unfortunately, this idea introduces a new risk when applied to generic library classes that are <em>not designed with null annotations in mind.</em> |
| A prominent example is method <code>java.util.Map.get(K)</code>, which declares to return <code>V</code>. |
| In this particular case, the javadoc of said method explicitly states that <code>null</code> is a possible return value, |
| which is in conflict with substituting <code>V</code> by any nonnull type. |
| So, if this specific method <code>get()</code> is invoked on a variable of type <code>Map<Y,@NonNull X></code>, |
| it is <em>unsafe</em> to assume that the return value is nonnull. |
| This dilemma is a combination of two factors: |
| </p> |
| <ol> |
| <li>The library lacks null annotations (it should be considered as "legacy" in terms of null annotations)</li> |
| <li>The compiler cannot know whether an unannotated type variable is by intention (as to support arbitrary substitution) or an unsafe omission (legacy). |
| </ol> |
| <p> |
| To alert users about this risk, a specific warning is raised by the compiler: |
| </p> |
| <blockquote> |
| Unsafe interpretation of method return type as '@NonNull X' based on the receiver type 'Map<Y,@NonNull X>'. Type 'Map' doesn't seem to be designed with null type annotations in mind |
| </blockquote> |
| <p>The severity of this problem is controlled by a dedicated <a href="../reference/preferences/java/compiler/ref-preferences-errors-warnings.htm#unsafe_interpretation_generic_legacy">preference option</a>. |
| <p>In response to this warning, the resolution of the dilemma is to add null annotations to the generic class in question. |
| For the likely case that the current user is not the owner of the legacy library, |
| <a href="task-using_external_null_annotations.htm">external null annotations</a> should be used. |
| Then there are two options:</p> |
| <ol> |
| <li>For the given example, method <code>get(K)</code> should be declared to return <code>@Nullable V</code>. |
| </li> |
| <li>For the opposite case as exemplified by <code>List.get()</code>, the return type should be left unannotated. |
| In order to signal to the compiler that types are left <em>unannotated by intention</em>, |
| a stub external annotation file (.eea) should be created without inserting actual external annotations. |
| This will tell the compiler that this class is no longer to be considered as legacy, |
| and hence all signatures of this class should be interpreted verbatim according to the rules given above |
| (care must be taken that this is safe for all method in that class). |
| </li> |
| </ol> |
| <p>If an external annotation file is found, the specific warning about unsafe interpretation is not issued. |
| Finally, if a project is not yet configured for using external annotations for the given library, |
| the problem is softened to "info" severity. |
| </p> |
| |
| <h2 id="inference">Inference</h2> |
| <p> |
| With null type annotations affecting type arguments, the language features one |
| more location amenable to inference: during type inference for the invocation |
| of a generic method (lambda expression etc.), type inference shyly attempts to |
| also infer the appropriate null type annotations. Example: |
| </p> |
| <pre> <T> T check(T in) { return in; } |
| void test(@NonNull List<@Nullable String> someStrings) { |
| @NonNull List<@Nullable String> checked; |
| checked = check(someStrings); // inferring types for this invocation |
| ... |
| } |
| </pre> |
| <p> |
| In this trivial example, inference will indeed instantiate the generic parameter <code><T></code> |
| to <code>@NonNull List<@Nullable String></code>. More complex scenarios are inferred, too, |
| but no guarantee is made, that a possible solution will always be found. In case inference fails |
| to infer suitable null type annotations, users are advised to revert to explicitly specify |
| type arguments even of a generic method invocation. |
| </p> |
| |
| <h2 id="more_locations">More locations</h2> |
| <h3>Cast and instanceof</h3> |
| <p> |
| Syntactically, type annotations can be used also in casts and instanceof expressions. |
| For null annotations, however, this has limited value. |
| </p> |
| <p> |
| <strong>Casting</strong> to a null-annotated type is always an <em>unchecked cast</em> because the |
| compiler is not allowed to insert runtime checks that would make the cast meaningful. |
| If a runtime check is desired, please consider using a small helper function like: |
| </p> |
| <pre> static @NonNull <T> T castToNonNull(@Nullable T value, @Nullable String msg) { |
| if (value == null) throw new NullPointerException(msg); |
| return value; |
| } |
| </pre> |
| <p> |
| Casts affecting the type arguments of a generic type will always be unchecked casts due to erasure. |
| </p> |
| <p> |
| <strong>instanceof</strong> checks with null type annotations are not meaningful. |
| Hence the compiler flags this as illegal usage of a null type annotation. |
| </p> |
| <h3>Locations that are nonnull by definition</h3> |
| <p> |
| Syntactically, type annotations can also be used for |
| </p> |
| <ul> |
| <li>allocation expressions</li> |
| <li>method receiver (pseudo argument by the name of <strong>this</strong>)</li> |
| <li>catch parameter</li> |
| </ul> |
| <p> |
| In each of these constructs, the type is nonnull by definition. |
| Hence a null type annotation in one of these positions is flagged as illegal use. |
| This doesn't, however, restrict the use of null type annotations on type arguments |
| of the given type. |
| </p> |
| |
| <h2 id="compatibility">Compatibility</h2> |
| <p> |
| Migrating from declaration annotations to type annotations has a few unavoidable |
| implications, regarding the syntax, regarding project configuration and regarding |
| the semantics. |
| </p> |
| <h3 id="compatibility_syntax">Syntax</h3> |
| <p> |
| For two constructs the JLS introduces a syntactic change: |
| </p> |
| <table border="1" cellspacing="0" cellpadding="5" summary="Syntax Changes"> |
| <tr><th>Declaration Annotations (Java 7 or below)</th><th>Type Annotation (Java 8)</th></tr> |
| <tr><td><code>@NonNull String[]</code></td><td><code>String @NonNull[]</code></td></tr> |
| <tr><td><code>@NonNull java.lang.String</code></td><td><code>java.lang.@NonNull String</code></td></tr> |
| </table> |
| <p> |
| In both cases the new syntax has been introduced to provide more options. |
| </p> |
| <p> |
| For <strong>arrays</strong> a type annotation before the leaf element type will now denote |
| an array whose individual cells have the given nullness - here: cells cannot be null. |
| In Java 7 and below the same syntax expressed a property of the corresponding variable |
| and hence captured the nullness of the array itself. |
| To express the same using Java-8 type annotations, viz. that the array itself can or cannot be null, |
| the type annotation is placed before the square brackets denoting the array dimensions. |
| This implies that the old syntax is still valid, but its meaning has changed: |
| </p> |
| <pre> |
| // annotated leaf type: |
| @NonNull Object [] o1; |
| o1 = null; // OK |
| o1 = new Object[1]; |
| o1[0] = null; // NOT OK |
| ... |
| // annotated array type: |
| Object @NonNull[] o2; |
| o2 = null; // NOT OK |
| o2 = new Object[1]; |
| o2[0] = null; // OK |
| ... |
| // multi-dimensional array: |
| Object @NonNull[] @Nullable[] o3; |
| o3 = null; // NOT OK, outer array is nonnull |
| o3 = new Object[1] @Nullable[]; |
| o3[0] = null; // OK, inner array is nullable |
| </pre> |
| <p> |
| Unfortunately, checking proper initialization of an array with nonnull content |
| is beyond the capabilities of JDT's static analysis. |
| </p> |
| <p> |
| For <strong>qualified type names</strong> the type annotation must be placed directly preceding the |
| actual type name. This way it is possible to give different type annotations for |
| inner classes and their enclosing like in <code>org.project.@Immutable Outer.@Nullable Inner</code>. |
| This distinction, however, is not useful for null annotations, because the enclosing |
| of a non-static inner class is by definition always non-null. Users of null type |
| annotations only need to understand that the old syntax for this case is illegal |
| for type annotations and how to convert this into legal Java 8 code (see the table above). |
| </p> |
| <h3 id="compatibility_configuration">Project configuration</h3> |
| <p> |
| Properly designed annotation types can be distinguished by looking at their <code>@Target</code> |
| declaration (the use of null annotations lacking a <code>@Target</code> declaration is discouraged). |
| To support both styles of annotations, JDT has published a major update of the annotation |
| bundle <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/package-summary.html"><code>org.eclipse.jdt.annotation</code></a>: |
| Versions 1.1.x are old style declaration annotations; versions 2.0.0 and onward are type annotations. |
| By increasing the major version an incompatibility is signaled. Users are advised to |
| reference this library with an explicit version range, either <code>[1.1.0,2.0.0)</code> |
| for declaration annotations or <code>[2.0.0,3.0.0)</code> for type annotations. |
| </p> |
| <p> |
| The exact configuration depends of course on the flavor of project: |
| <dl> |
| <dt>Plain Java</dt> |
| <dd>JDT continues to offer a quickfix for copying the annotation library into the |
| project. The version will be determined by the compliance settings of the project.</dd> |
| <dt>Maven</dt> |
| <dd>Both versions of the annotation bundle will be published to <code>repo.eclipse.org</code>, |
| from where they can be consumed using the regular maven mechanisms: be sure to specify |
| the correct version; specifying <code><scope>compile</scope></code> is recommended |
| for this dependency.</dd> |
| <dt>OSGi / Eclipse</dt> |
| <dd>When developing OSGi bundles / Eclipse plugins the version range should be specified as |
| mentioned above. Unfortunately, OSGi doesn't support a concept of compile time dependencies. |
| The PDE specific mechanism in file <code>build.properties</code> is problematic because |
| it doesn't support specifying a version range. Thus the best approximation of the desired |
| semantics is to use a <code>Require-Bundle</code> dependency. |
| qualified with <code>resolution:=optional</code> in order to avoid forcing this dependency |
| on the runtime: |
| <pre> |
| Require-Bundle: ..., |
| org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional |
| </pre></dd> |
| </dl> |
| <h3 id="compatibility_semantics">Semantics – NonNullByDefault</h3> |
| <p> |
| While the fundamental semantics of null annotation remains unchanged, |
| the annotation <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/NonNullByDefault.html" |
| ><code>@NonNullByDefault</code></a> has been changed slightly: |
| </p> |
| <ul> |
| <li>This annotation can now affect more locations.</li> |
| <li>The locations to be affected can be fine tuned using the |
| <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/NonNullByDefault.html#value--" |
| ><code>value</code></a> property of the annotation |
| (see also the enum <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/DefaultLocation.html" |
| ><code>DefaultLocation</code></a>).</li> |
| <li>As a consequence, the notation for canceling a default from an outer scope has been changed, too: |
| <table border="1" cellspacing="0" cellpadding="5" summary="Cancelling a default"> |
| <tr><th>Declaration Annotations (Java 7 or below)</th><th>Type Annotation (Java 8)</th></tr> |
| <tr><td><code>@NonNullByDefault(false)</code></td><td><code>@NonNullByDefault({})</code></td></tr> |
| </table> |
| </li> |
| </ul> |
| <p> |
| Note, that the <code>value</code> property described here is only supported when using the annotation type |
| <code>org.eclipse.jdt.annotation.NonNullByDefault</code> supplied by Eclipse. |
| </p> |
| <p> |
| Although the Java 8 variant of |
| <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/NonNullByDefault.html" |
| ><code>@NonNullByDefault</code></a> affects more locations, two noteworthy exceptions exist |
| (as specified in <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/DefaultLocation.html" |
| ><code>DefaultLocation</code></a>): |
| <blockquote> |
| <strong> |
| Wildcards and the use of type variables are always excluded from |
| <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/NonNullByDefault.html" |
| ><code>@NonNullByDefault</code></a>. |
| </strong> |
| </blockquote> |
| <p> |
| By this rule, type variables and wildcards retain their intended properties as "unknowns" also in terms of nullness, |
| even when they appear in the context of |
| <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/annotation/NonNullByDefault.html" |
| ><code>@NonNullByDefault</code></a>. |
| </p> |
| |
| <h2 id="compiler_messages_explained">Compiler messages explained</h2> |
| <p> |
| In addition to |
| <a href="PLUGINS_ROOT/org.eclipse.jdt.doc.user/tasks/task-using_null_annotations.htm#compiler_messages_explained" |
| >compiler messages of the previous version</a> the following messages may be issued, |
| if null type annotations are enabled for analysis: |
| </p> |
| |
| <h3>General null type mismatch</h3> |
| <dl> |
| <dt><font color="SaddleBrown">Null type mismatch (type annotations): required 'X' but this expression has type 'Y'</font></dt> |
| <dd>In an assignment context null type annotations don't match. |
| Note that the mismatch may relate to any detail of the type (type argument, array element), not necessarily to the main type.</dd> |
| </dl> |
| <p> |
| All mismatches detected based on type annotations are prefixed with "<code>Null type mismatch (type annotations)</code>". |
| </p> |
| |
| <h3>Various expressions</h3> |
| <dl> |
| <dt><font color="SaddleBrown">Potential null pointer access: array element may be null</font></dt> |
| <dd>An array element is dereferenced, where the array type declares its elements as <code>@Nullable</code>.</dd> |
| <dt><font color="SaddleBrown">Potential null pointer access: this expression has a '@Nullable' type</font></dt> |
| <dd>Any expression at the left hand side of a dot has a type that is declared to be nullable.</dd> |
| <dt><font color="SaddleBrown">Redundant null check: comparing '@NonNull X' against null</font></dt> |
| <dd>An arbitrary expression known to have a @NonNull type is unnecessarily being compared against null.</dd> |
| </dl> |
| |
| <h3>Unchecked conversions</h3> |
| <dl> |
| <dt><font color="SaddleBrown">Null type safety (type annotations): The expression of type 'X' needs unchecked conversion to conform to '@NonNull X'</font></dt> |
| <dd>A value of an un-annotated type is being assigned to a variable of an annotated type. |
| Note that the mismatch may relate to any detail of the type (type argument, array element), not necessarily to the main type.</dd> |
| <dt><font color="SaddleBrown">Null type safety: Unchecked cast from X to '@N Y'</font></dt> |
| <dd>A value is casted to a null-annotated type, where the nullness is not checked at runtime by the cast.</dd> |
| </dl> |
| |
| <h3>Problems specific to generics</h3> |
| <dl> |
| <dt><font color="SaddleBrown">Null constraint mismatch: The type 'X' is not a valid substitute for the type parameter 'T'</font></dt> |
| <dd>Here the type parameter <code><T></code> has a constraint in one of the forms mentioned <a href="#typeParameters">above</a>. |
| The actual type argument <code>X</code>, however, doesn't conform to this constraint.</dd> |
| <dt><font color="SaddleBrown">This nullness annotation conflicts with a '@N' annotation which is effective on the same type parameter</font></dt> |
| <dd>A null annotation on a bound of a type parameter conflicts with another null annotation on another bound or on the type parameter itself.</dd> |
| <dt><font color="SaddleBrown">Contradictory null annotations: method was inferred as 'T foo(X)', but only one of '@NonNull' and '@Nullable' can be effective at any location</font></dt> |
| <dd>Type inference for a generic method invocation has produced a signature in which contradictory null annotations clash on the same element.<dd> |
| <dt><font color="SaddleBrown">Null type mismatch (type annotations): 'null' is not compatible to the free type variable 'T'</font></dt> |
| <dt><font color="SaddleBrown">Null type mismatch (type annotations): required 'T' but this expression has type '@Nullable T', where 'T' is a free type variable</font></dt> |
| <dt><font color="SaddleBrown">Null type safety: required '@NonNull' but this expression has type 'T', a free type variable that may represent a '@Nullable' type</font></dt> |
| <dt><font color="SaddleBrown">The field 'f' may not have been initialized, whereas its type 'T' is a free type variable that may represent a '@NonNull' type</font></dt> |
| <dt><font color="SaddleBrown">Potential null pointer access: this expression has type 'T', a free type variable that may represent a '@Nullable' type</font></dt> |
| <dd>These problems are specifically detected by <a href="#pessimistic_analysis">pessimistic analysis for free type variables</a>.</dd> |
| <dt><font color="SaddleBrown">Unsafe interpretation of method return type as '@NonNull X' based on the receiver type 'Map<Y,@NonNull X>'. Type 'Map' doesn't seem to be designed with null type annotations in mind</font></dt> |
| <dt><font color="SaddleBrown">Unsafe interpretation of method return type as '@NonNull X' based on substitution 'V=@NonNull X'. Declaring type 'Map<K,V>' doesn't seem to be designed with null type annotations in mind</font></dt> |
| <dd>This signals a particular dilemma regarding <a href="#substitution">substitution of type variables from a legacy library</a>. |
| </dl> |
| |
| |
| <h3>Lambda expressions and method references</h3> |
| For any mismatches in null annotations affecting lambda expressions or method references the corresponding |
| "descriptor" is mentioned (the single abstract method being implemented by the lambda / method reference). |
| This is useful for finding the origin of a null annotation that is not explicit at the current expression. |
| |
| |
| </body> |
| </html> |