The document discusses new features in Java 8 and Eclipse support for these features, including:
- Early access builds of Eclipse provide support for some Java 8 features like type annotations, default methods, and lambda expressions, though support is still evolving.
- The Java 8 features include default methods in interfaces to allow interface evolution, lambda expressions as a cleaner way to represent code as data than anonymous classes, and type annotations to allow pluggable type systems for constraints like nullness.
- The Eclipse Java development team is working to fully support these Java 8 features in Eclipse with IDE features like code completion and static analysis tools leveraging the new language features.
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
JDT embraces lambda expressions
1. 8
8
Srikanth Sankaran
IBM India
Stephan Herrmann
GK Software
BETA_JAVA8
2. 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
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
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
5. 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
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, 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:
8. 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!
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
12. 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"
13. Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 16
8
Java 7 Style of “Code as Data”
● Via anonymous classes
14. 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!
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 λ Syntax and 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 Typing Examples
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 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
21. 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
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, 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.
25. 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
26. JDT features in the works 8
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 30
27. JDT features in the works 8
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 31
28. JDT features in the works 8
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 32
29. JDT features in the works 8
Srikanth Sankaran, Stephan Herrmann: Eclipse and Java 8 - EclipseCon Europe 2013 # 33
31. 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
32. 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
33. 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
34. 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
35. 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?
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, 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”
45. 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
46. 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
47. 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 !