• Functional Interfaces and Default Methods • Java.util.function • Stream API • Repeating and Type Annotations • New Java Date/Time API • Java API additions • Nashorn JS Engine • Other stuffs
Support for JDK 8 – Eclipse 4.4 Luna (M6 partially compliant) – NetBeans 8 – IntelliJ IDEA 13.1 • Java™ Platform, Standard Edition 8 API Specification – http://docs.oracle.com/javase/8/docs/api/
the parameters is optional; 2. Using parentheses around the parameter is optional if you have only one parameter; 3. Using curly braces is optional (unless you need multiple statements); 4. The return keyword is optional if you have a single expression that returns a value. Lambda expressions
• Lambdas are said to be “capturing” if they access a non-static variable or object that was defined outside of the lambda body. For example, this lambda captures the variable x: int x = 5; return y -> x + y; Lambda expressions
the variables it captures must be “effectively final”. So, either they must be marked with the final modifier, or they must not be modified after they're assigned. – Non-capturing • Is as opposed to capturing lambdas. A non-capturing lambda is generally going to be more efficient than a capturing one, because a non-capturing lambda only needs to be evaluated once. Lambda expressions
a variable is assigned a new value, it can't be used within a lambda. The “final” keyword is not required, but the variable must be “effectively final”. This code does not compile: int count = 0; List<String> strings = Arrays.asList("a","b","c"); strings.forEach(s -> { count++; // error: can't modify the value of count }); Lambda expressions
thrown from inside a lambda, the functional interface must also declare that checked exception can be thrown. The exception is not propagated to the containing method. This code does not compile: void appendAll(Iterable<String> values, Appendable out) throws IOException { // doesn't help with the error values.forEach(s -> { out.append(s); // error: can't throw IOException here // Consumer.accept(T) doesn't allow it }); } There are ways to work around this: – define your own functional interface that extends Consumer and wrap the IOException through as a RuntimeException. (UncheckedIOException) Lambda expressions
examples above, a traditional continue is possible by placing a “return;” statement within the lambda. However, there is no way to break out of the loop or return a value as the result of the containing method from within the lambda. For example: final String secret = "foo"; boolean containsSecret(Iterable<String> values) { values.forEach(s -> { if (secret.equals(s)) { ??? // want to end the loop and return true, but can't } }); } Lambda expressions
introduced. • It can be placed on an interface to declare the intention of it being a functional interface. • It will cause the interface to refuse to compile unless you've managed to make it a functional interface.
to one of the interface called Functional interface. • Examples: new Thread( () -> System.out.println("hello world") ).start(); Comparator<String> c = (a, b) -> Integer.compare(a.length(), b.length());
functional interface can define as many default methods as it likes. • Why we need Default Methods? – R: Extensibility without breaking the implementor class.
default methods, the ability to add static methods to interfaces is a major change to the Java language. public interface Stream<T> extends BaseStream<T, Stream<T>> { ... public static<T> Stream<T> of(T... values) { return Arrays.stream(values); } ... }
package, java.util.function: – Function<T,R> - takes an object of type T and returns R; – Supplier<T> - just returns an object of type T; – Predicate<T> - returns a boolean value based on input of type T; – Consumer<T> - performs an action with given object of type T; – BiFunction - like Function but with two parameters; – BiConsumer - like Consumer but with two parameters; – BinaryOperator<T> - take two T's as input, return one T as output, useful for "reduce" operations. • It also comes with several corresponding interfaces for primitive types, such as: – IntConsumer – IntFunction<R> – IntPredicate – IntSupplier
to support functional-style operations on streams of values. • A stream is something like an iterator. The values “flow past” (analogy to a stream of water) and then they're gone. A stream can only be traversed once, then it's used up. Streams may also be infinite.
Sequential: The actions of a sequential stream occur in serial fashion on one thread. – Parallel: The actions of a parallel stream may be happening all at once on multiple threads. • Usually, dealing with a stream will involve these steps: 1. Obtain a stream from some source; 2. Perform one or more intermediate operations; 3. Perform one terminal operation.
– Intermediate: An intermediate operation keeps the stream open and allows further operations to follow. – Lazy operations (e.g. filter, map, flatMap, peek, distinct, sorted, limit e substream) – Terminal: A terminal operation must be the final operation invoked on a stream. Once a terminal operation is invoked, the stream is "consumed" and is no longer usable. (e.g. forEach, toArray, reduce, collect, min, max, count, anyMatch, allMatch, noneMatch, findFirst e findAny)
of stream operations to consider: – Stateful: imposes some new property on the stream, such as uniqueness of elements, or a maximum number of elements, or ensuring that the elements are consumed in sorted fashion. These are typically more expensive than stateless intermediate operations. – Short-circuiting : allows processing of a stream to stop early without examining all the elements. This is an especially desirable property when dealing with infinite streams; if none of the operations being invoked on a stream are short-circuiting, then the code may never terminate.
to be repeated. // the first of the month and every monday at 7am @Schedule(dayOfMont = "first") @Schedule(dayOfWeek = "Monday", hour = 7) public void doGoblinInvasion() { ... } • To do this there is a new method called obj.getAnnotationsByType(Class annotationClass) on Class, Constructor, Method, etc. It returns an array of all such annotations (or an empty array if there are none).
also be applied to the use of types. This new ability is primarily aimed at supporting type-checking frameworks, such as Checker. These frameworks help find errors in your code at compile time. // Class instance creation: new @Interned RocketShip(); // Type cast: notNullString = (@NonNull String) str; // implements clause: class ImmutableSet<T> implements @Readonly Set<@Readonly T> { ... } // Thrown exception declaration: void launchRocket() throws @Critical FireException { ... }
Date/Time API that is safer, easier to read, and more comprehensive than the previous API. • Java’s Calendar implementation has not changed much since it was first introduced and Joda-Time is widely regarded as a better replacement.
cal = Calendar.getInstance(); cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) + 2); // New Way LocalTime now = LocalTime.now(); LocalTime later = now.plus(2, ChronoUnit.HOURS);
use ZonedDateTime. // Leaving from San Francisco on July 20, 2013, at 7:30 p.m. LocalDateTime leaving = LocalDateTime.of(2013, Month.JULY, 20, 19, 30); ZoneId leavingZone = ZoneId.of("America/Los_Angeles"); ZonedDateTime departure = ZonedDateTime.of(leaving, leavingZone); // Flight is 10 hours and 50 minutes, or 650 minutes ZoneId arrivingZone = ZoneId.of("Asia/Tokyo"); departure.withZoneSameInstant(arrivingZone).plusMinutes(650); // Checks if the specified instant is in daylight savings. if (arrivingZone.getRules().isDaylightSavings(arrival.toInstant())) // LEAVING: Jul 20 2013 07:30 PM (America/Los_Angeles) // ARRIVING: Jul 21 2013 10:20 PM (Asia/Tokyo) (Asia/Tokyo standard time will be in effect.)
several enums, such as LocalDateTimeField and LocalPeriodUnit, for expressing things like “days” and “hours” instead of the integer constants used in the Calendar API. • Clock – The Clock can be used in conjunction with dates and times to help build your tests. During production a normal Clock can be used, and a different one during tests. //To get the default clock, use the following: Clock clock = Clock.systemDefaultZone(); //The Clock can then be passed into factory methods; LocalTime time = LocalTime.now(clock);
Calendar.toInstant() converts the Calendar object to an Instant. – GregorianCalendar.toZonedDateTime() converts a GregorianCalendar instance to a ZonedDateTime. – GregorianCalendar.from(ZonedDateTime) creates a GregorianCalendar object using the default locale from a ZonedDateTime instance. – Date.from(Instant) creates a Date object from an Instant. – Date.toInstant() converts a Date object to an Instant. – TimeZone.toZoneId() converts a TimeZone object to a ZoneId.
the java.util package for avoiding null return values (and thusNullPointerException). • Tony Hoare, the invention of the null reference in 1965 for the ALGOL W programming language. He calls The Billion Dollar Mistake. • Used in the Stream API or custom implementation
JavaScript engine for the Oracle JVM. • Nashorn is much faster since it uses the invokedynamic feature of the JVM. It also includes a command line tool (jjs). • Java Platform, Standard Edition Nashorn User's Guide http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/ • Command line Nashorn: jjs script.js
command-line tool, jdeps, is added that developers can use to understand the static dependencies of their applications and libraries. – Java Platform, Standard Edition Tools Reference http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jdeps.html – Usage: jdeps <options> <classes...> where <classes> can be a pathname to a .class file, a directory, a JAR file, or a fully-qualified class name.
for the class metadata are now allocated out of native memory. This means that you won’t have to set the “XX:PermSize” options anymore (they don’t exist). – This also means that you will get a “java.lang.OutOfMemoryError: Metadata space” error message instead of “java.lang.OutOfMemoryError: Permgen space” when you run out of memory. – This is part of the convergence of the Oracle JRockit and HotSpot JVMs.
subset profiles of the Java SE platform specification that developers can use to deploy. Compact1 have less than 14MB; Compact2 is about 18MB; Compact3 is about 21MB. For reference, the latest Java 7u21 SE Embedded ARMv5/Linux environment requires 45MB. • An Introduction to Java 8 Compact Profiles – https://blogs.oracle.com/jtc/entry/a_first_look_at_compact