File: optional-checker.tex

package info (click to toggle)
checker-framework-java 3.2.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 22,840 kB
  • sloc: java: 145,910; xml: 839; sh: 518; makefile: 401; perl: 26
file content (118 lines) | stat: -rw-r--r-- 4,755 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
\htmlhr
\chapterAndLabel{Optional Checker for possibly-present data}{optional-checker}

Java 8 introduced the \sunjavadoc{java.base/java/util/Optional.html}{Optional}
class, a container that is either empty or contains a non-null value.

Using \<Optional> is intended to help programmers remember to check whether
data is present or not.  However, \<Optional> itself is prone to misuse.
The article
\href{https://homes.cs.washington.edu/~mernst/advice/nothing-is-better-than-optional.html}{Nothing
  is better than the \<Optional> type} gives reasons to use
regular nullable references rather than \<Optional>.  However, if you do use
\<Optional>, then the Optional Checker will help you avoid
\<Optional>'s pitfalls.

Stuart Marks gave
\href{https://stuartmarks.wordpress.com/2016/09/27/vjug24-session-on-optional/}{7
  rules} to avoid problems with Optional:
\begin{enumerate}
\item
  Never, ever, use \<null> for an \<Optional> variable or return value.
\item
  Never use \sunjavadoc{java.base/java/util/Optional.html\#get()}{Optional.get()} unless you can prove that the Optional is present.
\item
  Prefer alternative APIs over
  \sunjavadoc{java.base/java/util/Optional.html\#isPresent()}{Optional.isPresent()}
  and \sunjavadoc{java.base/java/util/Optional.html\#get()}{Optional.get()}.
\item
  It's generally a bad idea to create an \<Optional> for the specific
  purpose of chaining methods from it to get a value.
\item
  If an Optional chain has a nested \<Optional> chain, or has an
  intermediate result of \<Optional>, it's probably too complex.
\item
  Avoid using \<Optional> in fields, method parameters, and collections.
\item
  Don't use an \<Optional> to wrap any collection type (\<List>, \<Set>,
  \<Map>).  Instead, use an empty collection to represent the absence of
  values.
\end{enumerate}

Rule \#1 is guaranteed by the Nullness Checker
(\chapterpageref{nullness-checker}).
Rules \#2--\#7 are guaranteed by the Optional Checker, described in this chapter.
(Exception:  Rule \#5 is not yet implemented and will be checked by the
Optional Checker in the future.)
% They are all AST checks that would be easy to add later.

Use of the Optional Checker guarantees that your program will not suffer a
\<NullPointerException> nor a \<NoSuchElementException> when calling
methods on an expression of \<Optional> type.


\sectionAndLabel{How to run the Optional Checker}{optional-run-checker}

\begin{Verbatim}
javac -processor optional MyFile.java ...
\end{Verbatim}


\sectionAndLabel{Optional annotations}{optional-annotations}

These qualifiers make up the Optional type system:

\begin{description}

% alternate name: PossiblyAbsent.  But, the Optional Javadoc is careful
% never to use the term "absent", and it's nice parallelism to have
% "Present" in the names of all the annotations.
\item[\refqualclass{checker/optional/qual}{MaybePresent}]
  The annotated \<Optional> container may or may not contain a value.
  This is the default type.

\item[\refqualclass{checker/optional/qual}{Present}]
  The annotated \<Optional> container definitely contains a (non-null) value.

\item[\refqualclass{checker/optional/qual}{PolyPresent}]
  indicates qualifier polymorphism (see Section~\ref{qualifier-polymorphism}).

\end{description}

The subtyping hierarchy of the Optional Checker's qualifiers is shown in
Figure~\ref{fig-optional-hierarchy}.

\begin{figure}
\includeimage{optional-subtyping}{3.5cm}
\caption{The subtyping relationship of the Optional Checker's qualifiers.}
\label{fig-optional-hierarchy}
\end{figure}


\sectionAndLabel{What the Optional Checker guarantees}{optional-guarantees}

The Optional Checker guarantees that your code will not throw an exception
due to use of an absent \<Optional> where a present \<Optional> is needed.
More specifically, the Optional Checker will issue a warning if you call
\sunjavadoc{java.base/java/util/Optional.html\#get()
}{get}
or
\sunjavadoc{java.base/java/util/Optional.html\#orElseThrow(java.util.function.Supplier)}{orElseThrow}
on a \<@MaybePresent Optional> receiver, because each of these methods
throws an exception if the receiver is an absent
\<Optional>.

The Optional Checker does not check nullness properties, such as requiring
that the argument to
\sunjavadoc{java.base/java/util/Optional.html\#of(T)}{of}
is non-null or guaranteeing that the result of
\sunjavadoc{java.base/java/util/Optional.html\#get()}{get}
is non-null.  To obtain such a guarantee, run both the Optional Checker and
the Nullness Checker (\chapterpageref{nullness-checker}).

As with any checker, the guarantee is subject to certain limitations (see
Section~\ref{checker-guarantees}).


%  LocalWords:  isPresent NoSuchElementException MaybePresent PolyPresent
%%  LocalWords:  orElseThrow