8 8 Srikanth Sankaran IBM India Stephan Herrmann GK Software BETA_JAVA8
8 Eclipse and Java™ 8 ● Java 8 features available in early access builds: – JSR308 - Type Annotations. – JEP120 - Repeating Annotations. – JEP118 - Method Parameter Reflection. – JSR269 - Pluggable Annotation Processor API & javax.lang.model API enhancements for Java 8. – Support for “code carrying” interface methods. ● Partial support for – Lambda Expressions & Method/Constructor references – Overload resolution & Type inference changes still evolving ● had been blocked by incomplete specification until late September Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 3
8 Eclipse and Java™ 8 ● IDE features available in early access builds: – Type annotations based static null analysis ● substantially complete, open issues exist – Code completion, code selection/navigation, search engine ● for completed features – Code formatter and code “reconciler” – IDE enablement support: ● AST API's, programmatic AST rewriting API support etc ● Full fledged IDE support work in high gear: – Early access build refreshes very soon. ● JDT team: – 12 committers + 1 contributor + 1 GSOC student + 2 past committers on consulting role. Java8 Java8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 4
8 New Kinds of Methods ● defender methods ● virtual extension methods ● static interface methods ● default methods Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 6
8 New Kinds of Methods Those are only 2 kinds :) ● Code carrying methods in interfaces: – static methods ● non-OO programming even in interfaces – default methods previous names: ● defender methods ● virtual extension methods Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 7
8 Default Methods - Intention ● Intention – support evolution of interfaces in libraries: add methods to an interface w/o breaking implementors – still legal: Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 8
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 9 8 Default Methods - Consequences ● Consequences – Java 8 has multiple inheritance, sort-of – but little help for corner cases Root m() Both Left D m() Right D m() resolve:
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 10 8 Default Methods - Consequences ● Consequences – Java 8 has multiple inheritance, sort-of – but little help for corner cases Both Left D m() Right m() The default method m() inherited from Left conflicts with another method inherited from Right Advice: Don't!
8 Default Methods - Compatibility ● Designed for compatibility during evolution ● For the price of compatibility – Recipe for disaster: ● implement java.util.List → compile against JRE 7 → OK ● upgrade to JRE 8 but compile as 1.7 The type MyList<E> must implement the inherited abstract method Collection<E>.stream() – Undefined compiler behavior ● 1.7 compiler cannot handle default methods (from .class) ● ecj and javac differ – no plans to assimilate ● depending on compiler implementation details, not specification Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 12
8 Default Methods - Compatibility ● Designed for compatibility during evolution ● For the price of compatibility – Recipe for disaster: ● implement java.util.List → compile against JRE 7 → OK ● upgrade to JRE 8 but compile as 1.7 The type MyList<E> must implement the inherited abstract method Collection<E>.stream() – Undefined compiler behavior ● 1.7 compiler cannot handle default methods (from .class) ● ecj and javac differ – no plans to assimilate ● depending on compiler implementation details, not specification Advice: Don't mix -source 1.7 & JRE8! Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 13
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 14 8 λ (JSR 335)
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 15 8 Introducing Lambda Expressions ● Lambda Expressions, Closures, Anonymous Methods – what is in a name ? ● A function + “captured state” (may have non-locals) – accessible even when outside of defining lexical scope ● Theoretical framework dates back several decades: – Lambda (1930's – Church, Lisp – 1958) – Closure (1960's - Landin, Scheme - 1975) – Common idiomatic device in functional programming. ● Paradigm of passing a "code block as data"
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 16 8 Java 7 Style of “Code as Data” ● Via anonymous classes
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 17 8 Java 7 Style of “Code as Data” ● Via anonymous classes So if lambda expressions help model "code as data" are they just old wine in a new bottle? No!
8 Lambda Expressions ● Eliminate thorny issues with anonymous classes – Verbose/clunky Syntax – Scoping ● anonymous classes introduce their own scopes ● interplay between names in enclosing scope ↔ inherited names – Capture ● can only capture explicitly final outer locals ● necessarily capture enclosing class instance (memory leaks) ● Lambdas – address the above, designed to be flexible & optimizable – much more pleasing & efficient to program with call backs – With default methods, enabled Collections overhaul. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 18
8 λ Syntax and Examples Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 20
8 Target typing ● Lambda expression is basically – an anonymous method – with possibly "captured" enclosing state ● At the grammar level, lambdas are expressions (duh!) – Can occur anywhere an expression can – Introduces severe complications in parsing. ● Legally however, – Lambda needs a context that defines a "target type" – Everywhere else will have to rejected by the compiler. – Assignment, initialization, casts, method/ctor invocation, lambda expression body, conditional expressions and return statements are contexts that provide target type. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 21
8 Target Typing Examples Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 22
8 Functional Interfaces ● The target type must be a functional interface ● Functional interface – Declares a single abstract method – Some methods don't count: ● Default & static methods - they are not abstract ● May freely redeclare java.lang.Object's methods – May be tagged with @FunctionalInterface to express intent ● So the lambda object implements the functional interface ● Another way of constructing objects – apart from the SE7 ways (new, reflection, serialization, clone ...) Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 23
8 Lambda Syntax examples – Parameter types ● explicit, or ● inferred from target functional interface methods – Body ● expression, or ● block. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 24 – () ● can be omitted if a singleton parameter
8 Lambda Syntax examples – Parameter types ● explicit, or Trade-off between conciseness of expression ● inferred from target functional interface methods – Body ● expression, or ● block. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 25 – () ● can be omitted if a singleton parameter vs clarity of code - in the hands of the programmer
8 Variable capture ● A lambda can refer to enclosing method's locals – Captured state constitutes the "referencing environment" – Compiler can infer finality – Captured state is not mutable. ● Properly: capture of "immutable outer local's value" – Mutability of outer locals implies race conditions – Mutability would necessarily impose serial execution. – Lambda creation & invocation could be far apart. ● may be in different threads, may be after enclosing method return ● This "constraint" actually enables parallelism. ● Enclosing class instance captured only if referred to. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 26
8 Method References ● Similar to lambda expressions – Require a target type that must be a functional interface – Serve as instances of the functional interface – Rather than providing a method body, they refer to an existing method – Several variants offered. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 27
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 28 8 Lambda code generation ● Not lowered into anonymous classes - i.e not just syntactic sugar ● What does the following print ? ● Lambda object creation under the hood: – Handled by "Lambda metafactory" API in JRE. – Compilers generates suitable calls to the metafactory. – Enables various optimizations.
8 Putting it all together ● Here is a nice example from SOTL[*] [*] http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 29
JDT features in the works 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 30
JDT features in the works 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 31
JDT features in the works 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 32
JDT features in the works 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 33
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 35 8 @ (JSR 308)
8 Annotations in more Places ● Java 5: annotate declarations – ElementType: packages, classes, fields, methods, locals … ● Java 8: annotate types – ElementType.TYPE_USE – ElementType.TYPE_PARAMETER So what? Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 36
8 Why Care About Types? ● Type = Constraints on values To detect anomalies – missing capability – incompatible assignment – undeclared capability ● Constraint checking avoids errors – No Such Method / Field ● Basic statically typed OO – ClassCastException ● Generics – ??ExcepMtioyn pet example: NullPointerException Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 37
Let the Type System 8 Handle Nullity ● Ideally: Java would force explicit choice – String definitely a String, never null – String? either a String or null – Type system ensures: no dereferencing of null ● Nullity as a language feature? – Heavy weight, incompatible change – Language change for each new constraint? Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 38
8 Pluggable Type System ● Make it easier to add new constraints – Only one new syntax for all kinds of constraints ● Make it easier to add new type checkers – Checker Framework (Michael Ernst – U of Washington) ● Examples – @NonNull – @Interned equals(== , equals) – @Immutable value cannot change (Java 5 ?) – @ReadOnly value cannot change via this reference – @UI code requires to run on the SWT UI thread Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 39
Can't Java 5 Do All This? @Target(ElementType.PARAMETER) @interface NonNull5 {} void java5(@NonNull5 String arg); arg is qualified to be non-null @Target(ElementType.TYPE_USE) @interface NonNull8 {} void java8(@NonNull8 String arg); String is qualified to be non-null String is qualified to be non-null @Target(ElementType.METHOD) @interface NonNull5 {} @NonNull5 String java5(); java5 is qualified to be non-null Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 40 8 @Target(ElementType.TYPE_USE) @interface NonNull8 {} @NonNull8 String java8(); ● We've been lying about the method result – but we can't lie about everything, e.g.: void printFirstDog(@NonNull List<Dog> dogs) { dogs.get(0).bark(); } NPE?
l1 cannot contain null elements Null type mismatch: required '@NonNull String' but the provided value is null Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 41 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Null type mismatch: required '@NonNull String' but the provided value is null
l1 cannot contain null elements Null comparison always yields false: The variable first cannot be null at this location Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 42 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Null comparison always yields false: The variable first cannot be null at this location
l1 cannot contain null elements Null type safety (type annotations): The expression of type 'List<String>' needs unchecked conversion to conform to '@NonNull List<@NonNull String>' Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 43 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Null type safety (type annotations): The expression of type 'List<String>' needs unchecked conversion to conform to '@NonNull List<@NonNull String>'
l1 cannot contain null elements Null type mismatch (type annotations): required '@NonNull List<@NonNull String>' but this expression has type 'List<@Nullable String>' Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 44 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Null type mismatch (type annotations): required '@NonNull List<@NonNull String>' but this expression has type 'List<@Nullable String>'
l1 cannot contain null elements Potential null pointer access: The variable canNull may be null at this location Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 45 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Potential null pointer access: The variable canNull may be null at this location
8 Framework Development (1) ● So you want to be smart: public interface ILib<E> { @NonNull E work(@Nullable E e); } ● But will clients like it? public class LibImpl implements ILib<String> { @Override public @Nullable String work(@NonNull String e) { return null; } ● If thou usest annotations know thy co/contravariance – @Nullable parameter is irreversible – Design bug in guava's Predicate / Function Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 47 }
8 Framework Development (2) ● Avoid overspecification, make interfaces null-generic: public interface Function<I,O> { O apply(I in); } ● Let clients decide class ToString implements Function<@NonNull Object, @Nullable String> { @Override public @Nullable String apply(@NonNull Object o) { return o.toString(); } No NPE! Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 48 } ● Putting the pieces together <@NonNull I, @Nullable O> Collection<O> map1(Collection<I> in, Function<I, O> f) { … } <@Nullable I, @NonNull O> Collection<O> map2(Collection<I> in, Function<I, O> f) { … } ... List<@NonNull Object> in = new ArrayList<>(); Collection<@Nullable String> out = map1(in, new ToString());
8 Caveat: Arrays void test (@NonNull String [] stringsOrNulls) { System.out.println(stringsOrNulls[0]); ● Semantics are changing from Java 7 to Java 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 49 } array of nonnull elements the array can still be null Þ NPE void test (String @NonNull [] stringsOrNulls) { System.out.println(stringsOrNulls[0]); } nonnull array NPE- safe (but may print “null”)
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 50 8 Status: Annotated Type Analysis ● Implemented EA: @NonNull, @Nullable – Much analysis already performed ● known & unknown bugs – Editor may show more bogus errors ● Project > Clean and Problems View ● Planned: @Uninterned ● Proposed: @UiEffect, @Ui … – by [Colin S. Gordon, Werner Dietl, Michael D. Ernst, and Dan Grossman] – SWT: bye, bye, “Invalid thread access”
8 Status: Type Annotations ● Supported by – Compiler – DOM AST – APT ● Work in progress – respect during CCttrrll CCttrrll 1 CAtlrtl T ● Not yet supported by – Java model Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 51
8 TypeBinding Backstage Story aka “Symbol” ● Type bindings are “interned” – OK to use == ● Broken by encoding type annotations in type bindings ● Solution – Find/replace == comparisons for T <: TypeBinding – Tweak our compiler to do this – Plan: publish the tweak, controlled by @Uninterned Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 52
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 53 8 Dramatis personæ ● Jay Arthanareeswaran ● Anirban Chakarborty ● Manoj Palat ● Shankha Banerjee ● Manju Mathew ● Noopur Gupta ● Deepak Azad ● Srikanth Sankaran ● Olivier Thomann ● Andy Clement ● Michael Rennie ● Jesper S. Møller ● Walter Harley ● Stephan Herrmann ● Dani Megert ● Markus Keller ● Early Access: – http://wiki.eclipse.org/JDT_Core/Java8 ● We invite you to test - defect reports welcome !

JDT embraces lambda expressions

  • 1.
    8 8 SrikanthSankaran IBM India Stephan Herrmann GK Software BETA_JAVA8
  • 2.
    8 Eclipse andJava™ 8 ● Java 8 features available in early access builds: – JSR308 - Type Annotations. – JEP120 - Repeating Annotations. – JEP118 - Method Parameter Reflection. – JSR269 - Pluggable Annotation Processor API & javax.lang.model API enhancements for Java 8. – Support for “code carrying” interface methods. ● Partial support for – Lambda Expressions & Method/Constructor references – Overload resolution & Type inference changes still evolving ● had been blocked by incomplete specification until late September Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 3
  • 3.
    8 Eclipse andJava™ 8 ● IDE features available in early access builds: – Type annotations based static null analysis ● substantially complete, open issues exist – Code completion, code selection/navigation, search engine ● for completed features – Code formatter and code “reconciler” – IDE enablement support: ● AST API's, programmatic AST rewriting API support etc ● Full fledged IDE support work in high gear: – Early access build refreshes very soon. ● JDT team: – 12 committers + 1 contributor + 1 GSOC student + 2 past committers on consulting role. Java8 Java8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 4
  • 4.
    8 New Kindsof Methods ● defender methods ● virtual extension methods ● static interface methods ● default methods Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 6
  • 5.
    8 New Kindsof Methods Those are only 2 kinds :) ● Code carrying methods in interfaces: – static methods ● non-OO programming even in interfaces – default methods previous names: ● defender methods ● virtual extension methods Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 7
  • 6.
    8 Default Methods- Intention ● Intention – support evolution of interfaces in libraries: add methods to an interface w/o breaking implementors – still legal: Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 8
  • 7.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 9 8 Default Methods - Consequences ● Consequences – Java 8 has multiple inheritance, sort-of – but little help for corner cases Root m() Both Left D m() Right D m() resolve:
  • 8.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 10 8 Default Methods - Consequences ● Consequences – Java 8 has multiple inheritance, sort-of – but little help for corner cases Both Left D m() Right m() The default method m() inherited from Left conflicts with another method inherited from Right Advice: Don't!
  • 9.
    8 Default Methods- Compatibility ● Designed for compatibility during evolution ● For the price of compatibility – Recipe for disaster: ● implement java.util.List → compile against JRE 7 → OK ● upgrade to JRE 8 but compile as 1.7 The type MyList<E> must implement the inherited abstract method Collection<E>.stream() – Undefined compiler behavior ● 1.7 compiler cannot handle default methods (from .class) ● ecj and javac differ – no plans to assimilate ● depending on compiler implementation details, not specification Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 12
  • 10.
    8 Default Methods- Compatibility ● Designed for compatibility during evolution ● For the price of compatibility – Recipe for disaster: ● implement java.util.List → compile against JRE 7 → OK ● upgrade to JRE 8 but compile as 1.7 The type MyList<E> must implement the inherited abstract method Collection<E>.stream() – Undefined compiler behavior ● 1.7 compiler cannot handle default methods (from .class) ● ecj and javac differ – no plans to assimilate ● depending on compiler implementation details, not specification Advice: Don't mix -source 1.7 & JRE8! Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 13
  • 11.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 14 8 λ (JSR 335)
  • 12.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 15 8 Introducing Lambda Expressions ● Lambda Expressions, Closures, Anonymous Methods – what is in a name ? ● A function + “captured state” (may have non-locals) – accessible even when outside of defining lexical scope ● Theoretical framework dates back several decades: – Lambda (1930's – Church, Lisp – 1958) – Closure (1960's - Landin, Scheme - 1975) – Common idiomatic device in functional programming. ● Paradigm of passing a "code block as data"
  • 13.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 16 8 Java 7 Style of “Code as Data” ● Via anonymous classes
  • 14.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 17 8 Java 7 Style of “Code as Data” ● Via anonymous classes So if lambda expressions help model "code as data" are they just old wine in a new bottle? No!
  • 15.
    8 Lambda Expressions ● Eliminate thorny issues with anonymous classes – Verbose/clunky Syntax – Scoping ● anonymous classes introduce their own scopes ● interplay between names in enclosing scope ↔ inherited names – Capture ● can only capture explicitly final outer locals ● necessarily capture enclosing class instance (memory leaks) ● Lambdas – address the above, designed to be flexible & optimizable – much more pleasing & efficient to program with call backs – With default methods, enabled Collections overhaul. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 18
  • 16.
    8 λ Syntaxand Examples Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 20
  • 17.
    8 Target typing ● Lambda expression is basically – an anonymous method – with possibly "captured" enclosing state ● At the grammar level, lambdas are expressions (duh!) – Can occur anywhere an expression can – Introduces severe complications in parsing. ● Legally however, – Lambda needs a context that defines a "target type" – Everywhere else will have to rejected by the compiler. – Assignment, initialization, casts, method/ctor invocation, lambda expression body, conditional expressions and return statements are contexts that provide target type. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 21
  • 18.
    8 Target TypingExamples Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 22
  • 19.
    8 Functional Interfaces ● The target type must be a functional interface ● Functional interface – Declares a single abstract method – Some methods don't count: ● Default & static methods - they are not abstract ● May freely redeclare java.lang.Object's methods – May be tagged with @FunctionalInterface to express intent ● So the lambda object implements the functional interface ● Another way of constructing objects – apart from the SE7 ways (new, reflection, serialization, clone ...) Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 23
  • 20.
    8 Lambda Syntaxexamples – Parameter types ● explicit, or ● inferred from target functional interface methods – Body ● expression, or ● block. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 24 – () ● can be omitted if a singleton parameter
  • 21.
    8 Lambda Syntaxexamples – Parameter types ● explicit, or Trade-off between conciseness of expression ● inferred from target functional interface methods – Body ● expression, or ● block. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 25 – () ● can be omitted if a singleton parameter vs clarity of code - in the hands of the programmer
  • 22.
    8 Variable capture ● A lambda can refer to enclosing method's locals – Captured state constitutes the "referencing environment" – Compiler can infer finality – Captured state is not mutable. ● Properly: capture of "immutable outer local's value" – Mutability of outer locals implies race conditions – Mutability would necessarily impose serial execution. – Lambda creation & invocation could be far apart. ● may be in different threads, may be after enclosing method return ● This "constraint" actually enables parallelism. ● Enclosing class instance captured only if referred to. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 26
  • 23.
    8 Method References ● Similar to lambda expressions – Require a target type that must be a functional interface – Serve as instances of the functional interface – Rather than providing a method body, they refer to an existing method – Several variants offered. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 27
  • 24.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 28 8 Lambda code generation ● Not lowered into anonymous classes - i.e not just syntactic sugar ● What does the following print ? ● Lambda object creation under the hood: – Handled by "Lambda metafactory" API in JRE. – Compilers generates suitable calls to the metafactory. – Enables various optimizations.
  • 25.
    8 Putting itall together ● Here is a nice example from SOTL[*] [*] http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 29
  • 26.
    JDT features inthe works 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 30
  • 27.
    JDT features inthe works 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 31
  • 28.
    JDT features inthe works 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 32
  • 29.
    JDT features inthe works 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 33
  • 30.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 35 8 @ (JSR 308)
  • 31.
    8 Annotations inmore Places ● Java 5: annotate declarations – ElementType: packages, classes, fields, methods, locals … ● Java 8: annotate types – ElementType.TYPE_USE – ElementType.TYPE_PARAMETER So what? Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 36
  • 32.
    8 Why CareAbout Types? ● Type = Constraints on values To detect anomalies – missing capability – incompatible assignment – undeclared capability ● Constraint checking avoids errors – No Such Method / Field ● Basic statically typed OO – ClassCastException ● Generics – ??ExcepMtioyn pet example: NullPointerException Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 37
  • 33.
    Let the TypeSystem 8 Handle Nullity ● Ideally: Java would force explicit choice – String definitely a String, never null – String? either a String or null – Type system ensures: no dereferencing of null ● Nullity as a language feature? – Heavy weight, incompatible change – Language change for each new constraint? Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 38
  • 34.
    8 Pluggable TypeSystem ● Make it easier to add new constraints – Only one new syntax for all kinds of constraints ● Make it easier to add new type checkers – Checker Framework (Michael Ernst – U of Washington) ● Examples – @NonNull – @Interned equals(== , equals) – @Immutable value cannot change (Java 5 ?) – @ReadOnly value cannot change via this reference – @UI code requires to run on the SWT UI thread Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 39
  • 35.
    Can't Java 5Do All This? @Target(ElementType.PARAMETER) @interface NonNull5 {} void java5(@NonNull5 String arg); arg is qualified to be non-null @Target(ElementType.TYPE_USE) @interface NonNull8 {} void java8(@NonNull8 String arg); String is qualified to be non-null String is qualified to be non-null @Target(ElementType.METHOD) @interface NonNull5 {} @NonNull5 String java5(); java5 is qualified to be non-null Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 40 8 @Target(ElementType.TYPE_USE) @interface NonNull8 {} @NonNull8 String java8(); ● We've been lying about the method result – but we can't lie about everything, e.g.: void printFirstDog(@NonNull List<Dog> dogs) { dogs.get(0).bark(); } NPE?
  • 36.
    l1 cannot contain null elements Null type mismatch: required '@NonNull String' but the provided value is null Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 41 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Null type mismatch: required '@NonNull String' but the provided value is null
  • 37.
    l1 cannot contain null elements Null comparison always yields false: The variable first cannot be null at this location Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 42 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Null comparison always yields false: The variable first cannot be null at this location
  • 38.
    l1 cannot contain null elements Null type safety (type annotations): The expression of type 'List<String>' needs unchecked conversion to conform to '@NonNull List<@NonNull String>' Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 43 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Null type safety (type annotations): The expression of type 'List<String>' needs unchecked conversion to conform to '@NonNull List<@NonNull String>'
  • 39.
    l1 cannot contain null elements Null type mismatch (type annotations): required '@NonNull List<@NonNull String>' but this expression has type 'List<@Nullable String>' Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 44 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Null type mismatch (type annotations): required '@NonNull List<@NonNull String>' but this expression has type 'List<@Nullable String>'
  • 40.
    l1 cannot contain null elements Potential null pointer access: The variable canNull may be null at this location Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 45 8 void bad(List<String> unknown, List<@Nullable String> withNulls) { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add(null); String first = l1.get(0); if (first == null) return; l1 = unknown; l1 = withNulls; String canNull = withNulls.get(0); System.out.println(canNull.toUpperCase()); } @NonNull List<@Nullable String> l2 = new ArrayList<>(); l2 can contain null elements Annotated Generics void good() { @NonNull List<@NonNull String> l1 = new ArrayList<>(); l1.add("Hello"); for (String elem : l1) System.out.println(elem.toUpperCase()); l2.add(null); for (String unknown : l2) if (unknown != null) System.out.println(unknown.toUpperCase()); } Potential null pointer access: The variable canNull may be null at this location
  • 41.
    8 Framework Development(1) ● So you want to be smart: public interface ILib<E> { @NonNull E work(@Nullable E e); } ● But will clients like it? public class LibImpl implements ILib<String> { @Override public @Nullable String work(@NonNull String e) { return null; } ● If thou usest annotations know thy co/contravariance – @Nullable parameter is irreversible – Design bug in guava's Predicate / Function Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 47 }
  • 42.
    8 Framework Development(2) ● Avoid overspecification, make interfaces null-generic: public interface Function<I,O> { O apply(I in); } ● Let clients decide class ToString implements Function<@NonNull Object, @Nullable String> { @Override public @Nullable String apply(@NonNull Object o) { return o.toString(); } No NPE! Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 48 } ● Putting the pieces together <@NonNull I, @Nullable O> Collection<O> map1(Collection<I> in, Function<I, O> f) { … } <@Nullable I, @NonNull O> Collection<O> map2(Collection<I> in, Function<I, O> f) { … } ... List<@NonNull Object> in = new ArrayList<>(); Collection<@Nullable String> out = map1(in, new ToString());
  • 43.
    8 Caveat: Arrays void test (@NonNull String [] stringsOrNulls) { System.out.println(stringsOrNulls[0]); ● Semantics are changing from Java 7 to Java 8 Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 49 } array of nonnull elements the array can still be null Þ NPE void test (String @NonNull [] stringsOrNulls) { System.out.println(stringsOrNulls[0]); } nonnull array NPE- safe (but may print “null”)
  • 44.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 50 8 Status: Annotated Type Analysis ● Implemented EA: @NonNull, @Nullable – Much analysis already performed ● known & unknown bugs – Editor may show more bogus errors ● Project > Clean and Problems View ● Planned: @Uninterned ● Proposed: @UiEffect, @Ui … – by [Colin S. Gordon, Werner Dietl, Michael D. Ernst, and Dan Grossman] – SWT: bye, bye, “Invalid thread access”
  • 45.
    8 Status: TypeAnnotations ● Supported by – Compiler – DOM AST – APT ● Work in progress – respect during CCttrrll CCttrrll 1 CAtlrtl T ● Not yet supported by – Java model Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 51
  • 46.
    8 TypeBinding BackstageStory aka “Symbol” ● Type bindings are “interned” – OK to use == ● Broken by encoding type annotations in type bindings ● Solution – Find/replace == comparisons for T <: TypeBinding – Tweak our compiler to do this – Plan: publish the tweak, controlled by @Uninterned Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 52
  • 47.
    Srikanth Sankaran, StephanHerrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 53 8 Dramatis personæ ● Jay Arthanareeswaran ● Anirban Chakarborty ● Manoj Palat ● Shankha Banerjee ● Manju Mathew ● Noopur Gupta ● Deepak Azad ● Srikanth Sankaran ● Olivier Thomann ● Andy Clement ● Michael Rennie ● Jesper S. Møller ● Walter Harley ● Stephan Herrmann ● Dani Megert ● Markus Keller ● Early Access: – http://wiki.eclipse.org/JDT_Core/Java8 ● We invite you to test - defect reports welcome !