8 A A Deep Deep Dive Dive into into the the Void Void Advanced null Type Annotations Java 8 ready Stephan Herrmann GK Software 8 8 An Old Problem 1965 – Tony Hoare introduced Null references in ALGOL W – “simply because it was so easy to implement” Photograph by Rama, Wikimedia Commons, Cc-by-sa-2.0-fr ● Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 #2 Still Leading the Charts Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 8 #3 An Expensive Problem “The Billion Dollar Mistake” Photograph by Rama, Wikimedia Commons, Cc-by-sa-2.0-fr ● 8 Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 #4 8 Many Steps to a Solution ● – ● boooom method contracts – ● booooooom local flow analysis – ● booooooooom recognize patterns – ● Since Since ALGOL ALGOL W W do nothing: 1965 Since Since Eclipse Eclipse 3.1 3.1 Since Since Eclipse Eclipse Juno Juno // Java Java 55 boom type checking 2005 Since Since Eclipse Eclipse Luna Luna // Java Java 88 2012 2014 – Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 #5 Alternative Strategy ● 8 Optional – a polite way of saying: this value could be missing – supports null-less programming – doesn't help against existing nulls – viable option for from-scratch clean-room new software – requires all software to be re-written Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 #7 Obviously Correct ● Typechecking for null analysis ● Two kinds of types – – ● This is OK: ● These are type errors: 8 those that include null those that don't Dog? barkAndReturn(Dog dog) { dog.bark(); return null; } Dog barkAndReturn(Dog? dog) { dog.bark(); return null; } Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 #8 Typesystem Construction Kit Strategy ● Richer types – ● – ● JSR 308 ● add more information Richer type checking Type annotations – org.eclipse.jdt.annotation_2.0 @NonNull @Nullable ● new typing rules Stronger guarantees 8 ECJ checks nullness – ● compatibility & flow Stronger guarantees – proven absence of errors – no NPE – no methodNotUnderstood – no SWTExecption(thread) – no ClassCastException – … Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 #9 Ternary or Boolean? ● Buy @NonNull & @Nullable, get 3 kinds of types – ● – like using raw types in Java 5+ Null Nulltype typesafety safety(type (typeannotations): annotations):The Theexpression expressionof oftype type'List<String>' 'List<String>' needs needsunchecked uncheckedconversion conversionto toconform conformto to'@NonNull '@NonNullList<@NonNull List<@NonNullString>' String>' Nirwana: ubiquitous @NonNullByDefault – – – ● green, red, legacy Interfacing with legacy code – ● 8 per class / interface per package (use package-info.java) let the compiler complain about missing @NNBD And back to 2014 reality – @NonNullByDefault({}) Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 10 Where is: Everywhere? 8 TYPE_USE declarations DefaultLocation for @NonNullByDefault PARAMETER RETURN_TYPE FIELD TYPE_PARAMETER TYPE_BOUND TYPE_ARGUMENT ARRAY_CONTENTS @NonNullByDefault({ … }) class Foo <T extends Bar> { Foo<String> stringFoo; Bar[][] bars; Bar getBar(String name) { return bar; } } Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 11 Where is: Everywhere? 8 DefaultLocation for @NonNullByDefault ● Not supported – non-null by construction ● ● ● ● – would need runtime evaluation ● – instanceof & cast no usefull interpretation ● ● – new void void make(@A make(@A Foo Foo this) this) {} {} throws, catch argument this @A receiver in method reference @A Object::toString Object::toString @A @A Integer.MAX_VALUE Integer.MAX_VALUE prefix of static member constructor future ● type declaration Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 12 Where is: Everywhere? 8 ... ... Wildcards Wildcards and and the the use use of of type type variables variables are are always always excluded excluded from from NonNullByDefault. NonNullByDefault. DefaultLocation for @NonNullByDefault ● Not supported ● No default – local variables ● – better covered by flow analysis on type variables & wildcards ● these obtain nullness via other channels Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 13 Where is: Everywhere? 8 TYPE_USE declarations DefaultLocation for @NonNullByDefault PARAMETER RETURN_TYPE FIELD TYPE_PARAMETER TYPE_BOUND TYPE_ARGUMENT ARRAY_CONTENTS @NonNullByDefault({ … }) class Foo <T extends Bar> { Foo<String> stringFoo; Bar[][] bars; Bar getBar(String name) { return bar; } } Default default Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 14 Where is: Everywhere? 8 TYPE_USE declarations DefaultLocation for @NonNullByDefault PARAMETER RETURN_TYPE FIELD TYPE_PARAMETER TYPE_BOUND TYPE_ARGUMENT ARRAY_CONTENTS @NonNullByDefault({ … }) class Foo <T extends Bar> { Foo<String> stringFoo; Bar[][] bars; Bar getBar(String name) { return bar; } } Default default Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 15 Great Expectations ● ECJ will not “make” your program “null safe” ● It will hurt – – – ● pin-point ● design decisions you failed to make ● contradictory assumptions a false positive? type checker will need your help rules & obligations Application development – ● 8 free to move obligations around Tension in API design – – strict for effective null checking flexible for wide range of re-use Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 16 Generic API ● The classic declaration – ● Unconstrained type parameter: ● public interface List<T> { … } Client side – Free to choose the type argument: ● ● ● 8 List<@NonNull Person> List<@Nullable Person> Implementer – No knowledge about “free” type variable T – Must assume the worst ● ● need to check on dereference cannot assign null to a T variable Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 17 8 Constraining Type Parameters ● ● Admit only @NonNull types: annotated annotated type type bound bound – class MyGenericClass1<T extends @NonNull Object> – legal substitutes: @NonNull Object, @NonNull String – illegal: @Nullable Object – because @NonNull X <: @Nullable X Admit only @Nullable types: annotated annotated type type parameter parameter (declaration) (declaration) – we can't say <T super @Nullable Object> – class MyGenericClass2<@Nullable T> – (interpreted as both upper and lower bound) Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 18 Puzzle 1 ● 8 Legal or not? @NonNullByDefault class Tricky<T> { void foo(T t) {} void test() { foo(null); } Null Nulltype typemismatch mismatch(type (typeannotations): annotations): } 'null' 'null'isisnot notcompatible compatibleto tothe thefree freetype typevariable variable'T' 'T' – where does @NonNullByDefault apply ● type parameter? – ● no method parameter? – – ... ... Wildcards Wildcards and and the the use use of of type type variables variables are always excluded from NonNullByDefault. are always excluded from NonNullByDefault. generally yes but not to a type variable Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 19 Puzzle 2 ● 8 What is this? @NonNullByDefault class Tricky<T> { void foo(@Nullable T t) {} void test() { foo(null); } } ● “You said 'T' could mean anything” – so what is @Nullable T ? ● – e.g., if T := @NonNull String ? the @Nullable variant of whatever T represents ● e.g., @Nullable String Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 # 20 DEMO ● Double Inference ● External Annotations Stephan Herrmann: A Deep Dive into the Void - EclipseCon Europe 2014 8 # 21
© Copyright 2025 ExpyDoc