Info 4
Info 4
Table Of Contents
1. Introduction
2. New Features in Java language
2.1. Lambdas and Functional Interfaces
2.2. Interface Default and Static Methods
2.3. Method References
2.4. Repeating annotations
2.5. Better Type Inference
2.6. Extended Annotations Support
3. New Features in Java compiler
3.1. Parameter names
4. New Features in Java libraries
4.1. Optional
4.2. Streams
4.3. Date/Time API (JSR 310)
4.4. Nashorn JavaScript engine
4.5. Base64
4.6. Parallel Arrays
4.7. Concurrency
5. New Java tools
5.1. Nashorn engine: jjs
5.2. Class dependency analyzer: jdeps
6. New Features in Java runtime (JVM)
7. Conclusions
8. Resources
1. Introduction
With no doubts, Java 8 release is the greatest thing in the Java world since Java 5
(released quite a while ago, back in 2004). It brings tons of new features to the
Java as a language, its compiler, libraries, tools and the JVM (Java virtual
machine) itself. In this tutorial we are going to take a look on all these changes
and demonstrate the different usage scenarios on real examples.
The tutorial consists of several parts where each one touches the specific side of
the platform:
* language
* compiler
* libraries
* tools
* runtime (JVM)
In case lambda�s body is more complex, it may be wrapped into square brackets, as
the usual function definition in Java. For example:
Arrays.asList( "a", "b", "d" ).forEach( e -> {
System.out.print( e );
System.out.print( e );
} );
Lambdas may reference the class members and local variables (implicitly making them
effectively final if they are not). For example, those two snippets are equivalent:
String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach(
( String e ) -> System.out.print( e + separator ) );
And:
final String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach(
( String e ) -> System.out.print( e + separator ) );
Lambdas may return a value. The type of the return value will be inferred by
compiler. The return statement is not required if the lambda body is just a one-
liner. The two code snippets below are equivalent:
One thing to keep in mind: default and static methods do not break the functional
interface contract and may be declared:
@FunctionalInterface
public interface FunctionalDefaultMethods {
void method();
Lambdas are the largest selling point of Java 8. It has all the potential to
attract more and more developers to this great platform and provide state of the
art support for functional programming concepts in pure Java. For more details
please refer to official documentation.
The small code snippet below glues together the default methods and static methods
from the examples above.
The first type of method references is constructor reference with the syntax
Class::new or alternatively, for generics, Class< T >::new. Please notice that the
constructor has no arguments.
cars.forEach( Car::collide );
The third type is reference to instance method of arbitrary object of specific type
with the syntax Class::method. Please notice, no arguments are accepted by the
method.
cars.forEach( Car::repair );
And the last, fourth type is reference to instance method of particular class
instance the syntax instance::method. Please notice that method accepts exactly one
parameter of type Car.
Running all those examples as a Java program produces following output on a console
(the actual Car instances might be different):
Collided com.prabhat.java8.method.references.MethodReferences$Car@7a81197d
Repaired com.prabhat.java8.method.references.MethodReferences$Car@7a81197d
Following the com.prabhat.java8.method.references.MethodReferences$Car@7a81197d
For more examples and details on method references, please refer to official
documentation.
package com.prabhat.java8.repeatable.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target( ElementType.TYPE )
@Retention( RetentionPolicy.RUNTIME )
@Repeatable( Filters.class )
public @interface Filter {
String value();
};
@Filter( "filter1" )
@Filter( "filter2" )
public interface Filterable {
}
package com.prabhat.java8.type.inference;
package com.prabhat.java8.type.inference;
package com.prabhat.java8.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Collection;
}
}
@SuppressWarnings( "unused" )
public static void main(String[] args) {
final Holder< String > holder = new @NonEmpty Holder< String >();
}
}
package com.prabhat.java8.parameter.names;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
If you compile this class without using �parameters argument and then run this
program, you will see something like that:
Parameter: arg0
With �parameters argument passed to the compiler the program output will be
different (the actual name of the parameter will be shown):
Parameter: args
For experienced Maven users the �parameters argument could be added to the compiler
using configuration section of the maven-compiler-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<compilerArgument>-parameters</compilerArgument>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
Latest Eclipse Kepler SR2 release with Java 8 (please check out this download
instructions) support provides useful configuration option to control this compiler
setting as the picture below shows.
Java 8 adds a lot of new classes and extends existing ones in order to provide
better support of modern concurrency, functional programming, date/time, and many
more.
4.1. Optional
The famous NullPointerException is by far the most popular cause of Java
application failures. Long time ago the great Google Guavaproject introduced the
Optionals as a solution to NullPointerExceptions, discouraging codebase pollution
with null checks and encouraging developers to write cleaner code.
We are going to take a look on two small examples of Optional usages: with the
nullable value and with the value which does not allownulls.
The isPresent() method returns true if this instance of Optional has non-null value
and false otherwise. The orElseGet() method provides the fallback mechanism in case
Optional has null value by accepting the function to generate the default one. The
map()method transforms the current Optional�s value and returns the new Optional
instance. The orElse() method is similar to orElseGet()but instead of function it
accepts the default value. Here is the output of this program:
Full Name is set? false
Full Name: [none]
Hey Stranger!
4.2. Streams
The newly added Stream API (java.util.stream) introduces real-world functional-
style programming into the Java. This is by far the most comprehensive addition to
Java library intended to make Java developers significantly more productive by
allowing them to write effective, clean, and concise code.
Stream API makes collections processing greatly simplified (but it is not limited
to Java collections only as we will see later). Let us take start off with simple
class called Task.
@Override
public String toString() {
return String.format( "[%s, %d]", status, points );
}
}
}
Task has some notion of points (or pseudo-complexity) and can be either OPEN or
CLOSED. And then let us introduce a small collection of tasks to play with.
The first question we are going to address is how many points in total all OPEN
tasks have? Up to Java 8, the usual solution for it would be some sort of foreach
iteration. But in Java 8 the answers is streams: a sequence of elements supporting
sequential and parallel aggregate operations.
// Calculate total points of all active tasks using sum()
There are a couple of things going on here. Firstly, the tasks collection is
converted to its stream representation. Then, the filteroperation on stream filters
out all CLOSED tasks. On next step, the mapToInt operation converts the stream of
Tasks to the stream ofIntegersusing Task::getPoints method of the each task
instance. And lastly, all points are summed up using sum method, producing the
final result.
Before moving on to the next examples, there are some notes to keep in mind about
streams (more details here). Stream operations are divided into intermediate and
terminal operations.
Intermediate operations return a new stream. They are always lazy, executing an
intermediate operation such as filter does not actually perform any filtering, but
instead creates a new stream that, when traversed, contains the elements of the
initial stream that match the given predicate
Terminal operations, such as forEach or sum, may traverse the stream to produce a
result or a side-effect. After the terminal operation is performed, the stream
pipeline is considered consumed, and can no longer be used. In almost all cases,
terminal operations are eager, completing their traversal of the underlying data
source.
Yet another value proposition of the streams is out-of-the box support of parallel
processing. Let us take a look on this example, which does sums the points of all
the tasks.
It is very similar to the first example except the fact that we try to process all
the tasks in parallel and calculate the final result usingreduce method.
Here is the console output:
Total points (all tasks): 26.0
To finish up with the tasks example, let us calculate the overall percentage (or
weight) of each task across the whole collection, based on its points.
System.out.println( result );
The console output is just here:
[19%, 50%, 30%]
And lastly, as we mentioned before, the Stream API is not only about Java
collections. The typical I/O operations like reading the text file line by line is
a very good candidate to benefit from stream processing. Here is a small example to
confirm that.
The onClose method called on the stream returns an equivalent stream with an
additional close handler. Close handlers are run when the close() method is called
on the stream.
Stream API together with Lambdas and Method References baked by Interface�s Default
and Static Methods is the Java 8 response to the modern paradigms in software
development. For more details, please refer to official documentation.
Let us take a look on key classes and examples of their usages. The first class is
Clock which provides access to the current instant, date and time using a time-
zone. Clock can be used instead of
Other new classes we are going to look at are LocaleDate and LocalTime. LocaleDate
holds only the date part without a time-zone in the ISO-8601 calendar system.
Respectively, LocaleTime holds only the time part without time-zone in the ISO-8601
calendar system. Both LocaleDate and LocaleTime could be created from Clock.
System.out.println( date );
System.out.println( dateFromClock );
System.out.println( time );
System.out.println( timeFromClock );
The LocalDateTime combines together LocaleDate and LocalTime and holds a date with
time but without a time-zone in the ISO-8601 calendar system. A quick example is
shown below.
System.out.println( datetime );
System.out.println( datetimeFromClock );
If case you need a date/time for particular timezone, the ZonedDateTime is here to
help. It holds a date with time and with a time-zone in the ISO-8601 calendar
system. Here are a couple of examples for different timezones.
System.out.println( zonedDatetime );
System.out.println( zonedDatetimeFromClock );
System.out.println( zonedDatetimeFromZone );
And finally, let us take a look on Duration class: an amount of time in terms of
seconds and nanoseconds. It makes very easy to compute the different between two
dates. Let us take a look on that.
The example above computes the duration (in days and hours) between two dates, 16
April 2014 and 16 April 2015. Here is the sample output on a console:
Duration in days: 365
Duration in hours: 8783
The overall impression about Java 8�s new date/time API is very, very positive.
Partially, because of the battle-proved foundation it is built upon (Joda-Time),
partially because this time it was finally tackled seriously and developer voices
have been heard. For more details please refer to official documentation.
4.5. Base64
Finally, the support of Base64 encoding has made its way into Java standard library
with Java 8 release. It is very easy to use as following example shows off.
package com.prabhat.java8.base64;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
The console output from program run shows both encoded and decoded text:
QmFzZTY0IGZpbmFsbHkgaW4gSmF2YSA4IQ==
Base64 finally in Java 8!
package com.prabhat.java8.parallel.arrays;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
Arrays.parallelSetAll( arrayOfLong,
index -> ThreadLocalRandom.current().nextInt( 1000000 ) );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );
System.out.println();
Arrays.parallelSort( arrayOfLong );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );
System.out.println();
}
}
This small code snippet uses method parallelSetAll()to fill up arrays with 20000
random values. After that, the parallelSort() is being applied. The program outputs
first 10 elements before and after sorting so to ensure the array is really
ordered. The sample program output may look like that (please notice that array
elements are randomly generated):
Unsorted: 591217 891976 443951 424479 766825 351964 242997 642839 119108 552378
Sorted: 39 220 263 268 325 607 655 678 723 793
4.7. Concurrency
New methods have been added to the java.util.concurrent.ConcurrentHashMapclass to
support aggregate operations based on the newly added streams facility and lambda
expressions. Also, new methods have been added to the
java.util.concurrent.ForkJoinPoolclassto support a common pool (check also our free
course on Java concurrency).
The new java.util.concurrent.locks.StampedLockclass has been added to provide a
capability-based lock with three modes for controlling read/write access (it might
be considered as better alternative for infamous
java.util.concurrent.locks.ReadWriteLock).
New classes have been added to the java.util.concurrent.atomicpackage:
* DoubleAccumulator
* DoubleAdder
* LongAccumulator
* LongAdder
function f() {
return 1;
};
print( f() + 1 );
As an example, let us take a look on dependencies report for the popular Spring
Framework library. To make example short, let us analyze only one JAR file:
org.springframework.core-3.0.5.RELEASE.jar.
jdeps org.springframework.core-3.0.5.RELEASE.jar
This command outputs quite a lot so we are going to look on the part of it. The
dependencies are grouped by packages. If dependency is not available on a
classpath, it is shown as not found.
org.springframework.core-3.0.5.RELEASE.jar -> C:\Program
Files\Java\jdk1.8.0\jre\lib\rt.jar
org.springframework.core (org.springframework.core-3.0.5.RELEASE.jar)
-> java.io
-> java.lang
-> java.lang.annotation
-> java.lang.ref
-> java.lang.reflect
-> java.util
-> java.util.concurrent
-> org.apache.commons.logging not found
-> org.springframework.asm not found
-> org.springframework.asm.commons not found
org.springframework.core.annotation (org.springframework.core-3.0.5.RELEASE.jar)
-> java.lang
-> java.lang.annotation
-> java.lang.reflect
-> java.util
For more details please refer to official documentation.
7. Conclusions
The future is here: Java 8 moves this great platform forward by delivering the
features to make developers much more productive. It is too early to move the
production systems to Java 8 but in the next couples of months its adoption should
slowly start growing. Nevertheless the time is right to start preparing your code
bases to be compatible with Java 8 and to be ready to turn the switch once Java 8
proves to be safe and stable enough.
As a confirmation of community Java 8 acceptance, recently Pivotal released Spring
Framework 4.0.3 with production-ready Java 8 support.
Post a Comment
Blog Archive
? 2015 (6)
? May (1)
? February (5)
Multi Threading & Concurrency Interview Questions
Java 8 Features
Java Collection API Interview Questions
8 Brain-Busting Interview Questions Google Asks It...
Core Java Interview Questions