improved developer productivity in jdk8

44
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Improved Developer Productivity With Java SE 8 Simon Ritter Head of Java Technology Evangelism Oracle Corp Twitter: @speakjava Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Upload: simon-ritter

Post on 25-May-2015

1.810 views

Category:

Software


1 download

DESCRIPTION

Slides from GeekOut UK (16/10)

TRANSCRIPT

Page 1: Improved Developer Productivity In JDK8

Improved Developer Productivity With Java SE 8

Simon RitterHead of Java Technology EvangelismOracle Corp

Twitter: @speakjava

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Page 2: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 2

Safe Harbor StatementThe following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.

Page 3: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Java SE 8 New Features(Other Than Lambdas and Streams)

Page 4: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Annotations On Java Types

• Annotations can currently only be used on type declarations– Classes, methods, variable definitions

• Extension for places where types are used– e.g. parameters

• Permits error detection by pluggable type checkers– e.g. null pointer errors, race conditions, etc

public void process(@immutable List data) {…}

Page 5: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Concurrency Updates

• Scalable update variables– DoubleAccumulator, DoubleAdder, etc–Multiple variables avoid update contention– Good for frequent updates, infrequent reads

• ConcurrentHashMap updates– Improved scanning support, key computation

• ForkJoinPool improvements– Completion based design for IO bound applications– Thread that is blocked hands work to thread that is running

Page 6: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Parallel Array Sorting

• Additional utility methods in java.util.Arrays– parallelSort (multiple signatures for different primitives)

• Anticipated minimum improvement of 30% over sequential sort– For dual core system with appropriate sized data set

• Built on top of the fork-join framework– Uses Doug Lea’s ParallelArray implementation– Requires working space the same size as the array being sorted

Page 7: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Date And Time APIs

• A new date, time, and calendar API for the Java SE platform• Supports standard time concepts– Partial, duration, period, intervals– date, time, instant, and time-zone

• Provides a limited set of calendar systems and be extensible to others• Uses relevant standards, including ISO-8601, CLDR, and BCP47• Based on an explicit time-scale with a connection to UTC

Page 8: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

HTTP URL Permissions

• New type of network permission– Grant access in terms of URLs, rather than IP addresses

• Current way to specify network permissions– java.net.SocketPermission– Not restricted to just HTTP–Operates in terms of IP addresses only

• New, higher level capabilities– Support HTTP operations (POST, GET, etc)

Page 9: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Compact ProfilesApproximate static footprint goals

Compact1 Profile

Compact2 Profile

Compact3 Profile

Full JRE 54Mb

30Mb

16Mb

11Mb

Page 10: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Nashorn JavaScript Engine

• Lightweight, high-performance JavaScript engine– Integrated into JRE

• Use existing javax.script API• ECMAScript-262 Edition 5.1 language specification compliance• New command-line tool, jjs to run JavaScript• Internationalised error messages and documentation

Page 11: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Retire Rarely-Used GC Combinations

• Rarely used– DefNew + CMS– ParNew + SerialOld– Incremental CMS

• Large testing effort for little return• Will generate deprecated option messages–Won’t disappear just yet

Page 12: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Remove The Permanent Generation

• No more need to tune the size of it• Current objects moved to Java heap or native memory– Interned strings– Class metadata– Class static variables

• Part of the HotSpot, JRockit convergence

Permanently

Page 13: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Lambdas And Streams

Page 14: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

The Problem: External Iteration

List<Student> students = ...double highestScore = 0.0;for (Student s : students) { if (s.getGradYear() == 2011) { if (s.getScore() > highestScore) highestScore = s.score; }}

• Our code controls iteration• Inherently serial: iterate from

beginning to end• Not thread-safe

• Business logic is stateful• Mutable accumulator variable

Page 15: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Internal Iteration With Inner Classes

• Iteration handled by the library

• Not inherently serial – traversal may be done in parallel

• Traversal may be done lazily – so one pass, rather than three

• Thread safe – client logic is stateless

• High barrier to use– Syntactically ugly

More Functionaldouble highestScore = students

.filter(new Predicate<Student>() {

public boolean op(Student s) {

return s.getGradYear() == 2011;

}

})

.map(new Mapper<Student,Double>() {

public Double extract(Student s) {

return s.getScore();

}

})

.max();

Page 16: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Internal Iteration With LambdasList<Student> students = ...double highestScore = students .filter(Student s -> s.getGradYear() == 2011) .map(Student s -> s.getScore()) .max();

• More readable

• More abstract

• Less error-prone

NOTE: This is not JDK8 code

Page 17: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Lambda Expressions

• Lambda expressions represent anonymous functions– Same structure as a method• typed argument list, return type, set of thrown exceptions, and a body

– Not associated with a class

• We now have parameterised behaviour, not just values

Some Details

double highestScore = students. filter(Student s -> s.getGradYear() == 2011). map(Student s -> s.getScore()) max();

What

How

Page 18: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Lambda Expression Types

• Single-method interfaces are used extensively in Java– Definition: a functional interface is an interface with one abstract method– Functional interfaces are identified structurally– The type of a lambda expression will be a functional interface• Lambda expressions provide implementations of the abstract method

interface Comparator<T> { boolean compare(T x, T y); } interface FileFilter { boolean accept(File x); } interface Runnable { void run(); } interface ActionListener { void actionPerformed(…); } interface Callable<T> { T call(); }

Page 19: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Local Variable Capture

• Lambda expressions can refer to effectively final local variables from the enclosing scope• Effectively final: A variable that meets the requirements for final variables (i.e.,

assigned once), even if not explicitly declared final• Closures on values, not variables

void expire(File root, long before) { root.listFiles(File p -> p.lastModified() <= before);

}

Page 20: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

What Does ‘this’ Mean For Lambdas?

• ‘this’ refers to the enclosing object, not the lambda itself• Think of ‘this’ as a final predefined local• Remember the Lambda is an anonymous function– It is not associated with a class– Therefore there can be no ‘this’ for the Lambda

Page 21: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Referencing Instance VariablesWhich are not final, or effectively final

class DataProcessor { private int currentValue;

public void process() { DataSet myData = myFactory.getDataSet(); dataSet.forEach(d -> d.use(currentValue++)); }}

Page 22: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Referencing Instance VariablesThe compiler helps us out

class DataProcessor { private int currentValue;

public void process() { DataSet myData = myFactory.getDataSet(); dataSet.forEach(d -> d.use(this.currentValue++)); }}

‘this’ (which is effectively final) inserted by the compiler

Page 23: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Type Inference

• The compiler can often infer parameter types in a lambda expression Inferrence based on the target functional interface’s method signature

• Fully statically typed (no dynamic typing sneaking in)–More typing with less typing

List<String> list = getList();Collections.sort(list, (String x, String y) -> x.length() - y.length());

Collections.sort(list, (x, y) -> x.length() - y.length());

static T void sort(List<T> l, Comparator<? super T> c);

Page 24: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Method And Constructor References

• Method references let us reuse a method as a lambda expression

• Same syntax works for constructors

FileFilter x = File f -> f.canRead();

FileFilter x = File::canRead;

Factory<List<String>> f = ArrayList<String>::new;

Page 25: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Library Evolution

Page 26: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Library Evolution Goal

• Requirement: aggregate operations on collections–New methods required on Collections to facilitate this

• This is problematic– Can’t add new methods to interfaces without modifying all implementations– Can’t necessarily find or control all implementations

int heaviestBlueBlock = blocks .filter(b -> b.getColor() == BLUE) .map(Block::getWeight) .reduce(0, Integer::max);

Page 27: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Solution: Default Methods

• Specified in the interface• From the caller’s perspective, just an ordinary interface method• Provides a default implementation• Default only used when implementation classes do not provide a body for the

extension method• Implementation classes can provide a better version, or not

interface Collection<E> { default Stream<E> stream() { return StreamSupport.stream(spliterator()); } }

Page 28: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Virtual Extension Methods

• Err, isn’t this implementing multiple inheritance for Java? • Yes, but Java already has multiple inheritance of types• This adds multiple inheritance of behavior too• But not state, which is where most of the trouble is• Can still be a source of complexity • Class implements two interfaces, both of which have default methods• Same signature• How does the compiler differentiate?

• Static methods also allowed in interfaces in Java SE 8

Stop right there!

Page 29: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Functional Interface Definition

• Single Abstract Method (SAM) type• A functional interface is an interface that has one abstract method– Represents a single function contract– Doesn’t mean it only has one method

• @FunctionalInterface annotation– Helps ensure the functional interface contract is honoured– Compiler error if not a SAM

Page 30: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Lambdas In Full Flow:Streams

Page 31: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Stream Overview

• A stream pipeline consists of three types of things– A source– Zero or more intermediate operations– A terminal operation• Producing a result or a side-effect

Pipeline

int total = transactions.stream() .filter(t -> t.getBuyer().getCity().equals(“London”)) .mapToInt(Transaction::getPrice) .sum();

Source

Intermediate operationTerminal operation

Page 32: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Stream Sources

• From collections and arrays– Collection.stream()– Collection.parallelStream()– Arrays.stream(T array) or Stream.of()

• Static factories– IntStream.range()– Files.walk()

• Roll your own– java.util.Spliterator

Many Ways To Create

Page 33: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Stream Terminal Operations

• The pipeline is only evaluated when the terminal operation is called– All operations can execute sequentially or in parallel– Intermediate operations can be merged• Avoiding multiple redundant passes on data• Short-circuit operations (e.g. findFirst)• Lazy evaluation

– Stream characteristics help identify optimisations• DISTINT stream passed to distinct() is a no-op

Page 34: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Optional Class

• Terminal operations like min(), max(), etc do not return a direct result• Suppose the input Stream is empty?• Optional<T>– Container for an object reference (null, or real object)– Think of it like a Stream of 0 or 1 elements– use get(), ifPresent() and orElse() to access the stored reference– Can use in more complex ways: filter(), map(), etc

Helping To Eliminate the NullPointerException

Page 35: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Example 1Convert words in list to upper case

List<String> output = wordList .stream() .map(String::toUpperCase) .collect(Collectors.toList());

Page 36: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Example 1Convert words in list to upper case (in parallel)

List<String> output = wordList .parralelStream() .map(String::toUpperCase) .collect(Collectors.toList());

Page 37: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Example 2

• BufferedReader has new method– Stream<String> lines()

Count lines in a file

long count = bufferedReader .lines() .count();

Page 38: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Example 3Join lines 3-4 into a single string

String output = bufferedReader .lines() .skip(2) .limit(2) .collect(Collectors.joining());

Page 39: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Example 4Collect all words in a file into a list

List<String> output = reader .lines() .flatMap(line -> Stream.of(line.split(REGEXP))) .filter(word -> word.length() > 0) .collect(Collectors.toList());

Page 40: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Example 5List of unique words in lowercase, sorted by length

List<String> output = reader .lines() .flatMap(line -> Stream.of(line.split(REGEXP))) .filter(word -> word.length() > 0) .map(String::toLowerCase) .distinct() .sorted((x, y) -> x.length() - y.length()) .collect(Collectors.toList());

Page 41: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Example 6: Real WorldInfinite stream from thermal sensor

private int double currentTemperature;...

thermalReader .lines() .mapToDouble(s -> Double.parseDouble(s.substring(0, s.length() - 1))) .map(t -> ((t – 32) * 5 / 9) .filter(t -> t != currentTemperature) .peek(t -> listener.ifPresent(l -> l.temperatureChanged(t))) .forEach(t -> currentTemperature = t);

Page 42: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Example 6: Real WorldInfinite stream from thermal sensor

private int double currentTemperature;...

thermalReader .lines() .mapToDouble(s -> Double.parseDouble(s.substring(0, s.length() - 1))) .map(t -> ((t – 32) * 5 / 9) .filter(t -> t != this.currentTemperature) .peek(t -> listener.ifPresent(l -> l.temperatureChanged(t))) .forEach(t -> this.currentTemperature = t);

Page 43: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Conclusions

• Java SE 8 is a significant change to Java– New features in language, libraries and VM

• Java needs lambda statements – Significant improvements in existing libraries are required

• Require a mechanism for interface evolution– Solution: virtual extension methods

• Bulk operations on Collections–Much simpler with Lambdas

• Java will continue to evolve to meet developer's needs

Page 44: Improved Developer Productivity In JDK8

Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

Graphic Section Divider