lect20-create-typesystem
lect20-create-typesystem
CSE 331
University of Washington
Michael Ernst
Motivation
java.lang.NullPointerException
java.lang.NullPointerException
Java's type system is too weak
Type checking prevents many errors
int i = "hello";
System.console().readLine();
Java's type system is too weak
Type checking prevents many errors
int i = "hello";
Optional<String> maidenName;
Optional reminds you to check
Without Optional: With Optional:
possible possible
NullPointerException NoSuchElementException
String mName; Optional<String> omName;
mName.equals(...); omName.get().equals(...);
if (mName != null) { if (omName.isPresent()) {
mName.equals(...); omName.get().equals(...);
} } possible
Complex rules for using Optional correctly! NullPointerException
Other guidelines from:
Stephen Colebourne, Edwin
How not to use Optional Dalorzo, Vasco Ferreira C.,
Brian Goetz, Daniel
Olszewski, Nicolai Parlog,
Oleg Shelajev, ...
Stuart Marks’s rules:
1. Never, ever, use null for an Optional variable or return value.
2. Never use Optional.get() unless you can prove that the Optional is present.
3. Prefer alternative APIs over Optional.isPresent() and Optional.get().
4. It’s generally a bad idea to create an Optional for the specific purpose of
Let’s enforce the
chaining methods from it to get a value.
5. rules with a tool.
If an Optional chain has a nested Optional chain, or has an intermediate
result of Optional, it’s probably too complex.
6. Avoid using Optional in fields, method parameters, and collections.
7. Don’t use an Optional to wrap any collection type (List, Set, Map). Instead,
use an empty collection to represent the absence of values.
Which rules to enforce with a tool
Stuart Marks’s rules:
1. Never, ever, use null for an Optional variable or return value.
2. Never use Optional.get() unless you can prove that the Optional is present.
3. Prefer alternative APIs over Optional.isPresent() and Optional.get().
4. It’s generally a bad idea to create an Optional for the specific purpose of
chaining methods from it to get a value.
5. If an Optional chain has a nested Optional chain, or has an intermediate
result of Optional, it’s probably too complex.
6. Avoid using Optional in fields, method parameters, and collections.
7. Don’t use an Optional to wrap any collection type (List, Set, Map). Instead,
use an empty collection to represent the absence of values.
Which rules to enforce with a tool
Stuart Marks’s rules:
1. Never, ever, use null for an Optional variable or return value.
2. Never use Optional.get() unless you can prove that the Optional is present.
3. Prefer alternative APIs over Optional.isPresent() and Optional.get().
4. It’s generally a bad idea to create an Optional for the specific purpose of
These are
chaining methods from it to get a value.
5. type system properties.
If an Optional chain has a nested Optional chain, or has an intermediate
result of Optional, it’s probably too complex.
6. Avoid using Optional in fields, method parameters, and collections.
7. Don’t use an Optional to wrap any collection type (List, Set, Map). Instead,
use an empty collection to represent the absence of values.
Define a type system
Define a type system
1. Type hierarchy (subtyping)
2. Type rules (what operations are illegal)
3. Type introduction (what types for literals, …)
4. Dataflow (run-time tests)
@Nullable @NonNull
@NonNull @Nullable
@NonNull @Nullable
2 pieces of information:
● the types
● their relationships
Type hierarchy for nullness
@Nullable
@Nullable @NonNull
@NonNull @Null
@NonNull @Nullable
2 pieces of information:
● the types
● their relationships
Type hierarchy for Optional
“Never use Optional.get() unless you can prove that the Optional is present.”
@Maybe
@Nullable
Present
@NonNull @Present
2 pieces of information:
● the types
● their relationships
Type = type qualifier + Java basetype
@Present Optional<String> maidenName;
Type qualifier Java basetype
Type @MaybePresent
Optional<String>
expr.getValue()
receiver must be non-null
● synchronized (expr) { … }
monitor must be non-null
● ...
@MaybePresent
myOptional.get()
class Optional<T> {
T get() { … } example call:
} a.equals(b)
@MaybePresent
myOptional.get()
class Optional<T> {
T get(Optional<T> this) { … }
}
@MaybePresent
myOptional.get()
class Optional<T> {
T get(@Present Optional<T> this) {…}
}
@MaybePresent
myOptional.get()
class Optional<T> {
T get(@Present Optional<T> this) {…}
T orElseThrow(@Present O… this, …) {…}
}
Define a type system
1. Type hierarchy (subtyping)
2. Type rules (what operations are illegal)
3. Type introduction (what types for literals…)
4. Dataflow (run-time tests)
Type introduction rules
For Nullness type system:
● null : @Nullable
http://CheckerFramework.org/