Popular Posts

Friday, May 22, 2015

Java new Features Enhancements J2SE / JDK 8/7/6/5 – Main Changes

Java Programming Language Updates in latest version / revision (5/6/7/8):

Java 5 changes:

Enhanced for Loop
Typesafe Enums
Static Import

Metadata (Annotations)

1. Generics
When you take an element out of a Collection, you must cast it to the type of element that is stored in the collection. Besides being inconvenient, this is unsafe. The compiler does not check that your cast is the same as the collection's type, so the cast can fail at run time.

Generics provides a way for you to communicate the type of a collection to the compiler, so that it can be checked. Once the compiler knows the element type of the collection, the compiler can check that you have used the collection consistently and can insert the correct casts on values being taken out of the collection.

Here is a simple example taken from the existing Collections tutorial:
// Removes 4-letter words from c. Elements must be strings
static void expurgate(Collection c) {
    for (Iterator i = c.iterator(); i.hasNext(); )
      if (((String) i.next()).length() == 4)

Here is the same example modified to use generics:
// Removes the 4-letter words from c
static void expurgate(Collection c) {
    for (Iterator i = c.iterator(); i.hasNext(); )
      if (i.next().length() == 4)

When you see the code , read it as “of Type”; the declaration above reads as “Collection of String c.” The code using generics is clearer and safer. We have eliminated an unsafe cast and a number of extra parentheses. More importantly, we have moved part of the specification of the method from a comment to its signature, so the compiler can verify at compile time that the type constraints are not violated at run time. Because the program compiles without warnings, we can state with certainty that it will not throw a ClassCastException at run time. The net effect of using generics, especially in large programs, is improved readability and robustness.

Enhancements in Java SE 8

* Lambda Expressions enable you to encapsulate a single unit of behavior and pass it to other code. You can use a lambda expressions if you want a certain action performed on each element of a collection, when a process is completed, or when a process encounters an error. Lambda expressions are supported by the following features:

* Method References are compact, easy-to-read lambda expressions for methods that already have a name.

* Default Methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces. They are interface methods that have an implementation and the default keyword at the beginning of the method signature. In addition, you can define static methods in interfaces.

* New and Enhanced APIs That Take Advantage of Lambda Expressions and Streams in Java SE 8 describe new and enhanced classes that take advantage of lambda expressions and streams.

* Improved Type Inference - The Java compiler takes advantage of target typing to infer the type parameters of a generic method invocation. The target type of an expression is the data type that the Java compiler expects depending on where the expression appears. For example, you can use an assignment statement's target type for type inference in Java SE 7. However, in Java SE 8, you can use the target type for type inference in more contexts. The most prominent example is using a method invocation's target types to infer the data types of its arguments.

Consider the following example:

List stringList = new ArrayList<>();

Disregarding generics for the moment, the method addAll expects a Collection instance
as its argument, and the method Arrays.asList returns a List instance. This works because List is a subtype of Collection. Now considering generics, the target type of addAll is Collection, and Arrays.asList returns a List instance. In this example, the Java SE 8 compiler can infer that the value of the type variable T is String. The compiler infers this from the target type Collection.

Compilers from Java SE 7 and earlier do not accept this code because they do not use target typing to infer types for method call arguments. For example, the Java SE 7 compiler generates an error message similar to the following:

error: no suitable method found for addAll(List method List.addAll(Collection) is not applicable (actual argument List invocation conversion)

Consequently, in situations like this where the Java compiler cannot infer types, you must explicitly specify values for type variables with type witnesses. For example, the following works in Java SE 7:

List stringList = new ArrayList<>();
See the following sections in the Java Tutorials for more information:

o Target Typing in Lambda Expressions
o Type Inference

Annotations on Java Types - It is now possible to apply an annotation anywhere a type
is used. Used in conjunction with a pluggable type system, this allows for stronger type
checking of your code. For more information, see Type Annotations and Pluggable
Type Systems in the new Annotations lesson in the Java Tutorial.

Repeating Annotations - It is now possible to apply the same annotation type more than
once to the same declaration or type use. For more information, see Repeating
Annotations in the new Annotations lesson in the Java Tutorial.

Method Parameter Reflection - You can obtain the names of the formal parameters of
any method or constructor with the method java.lang.reflect.Executable.getParameters. (The
classes Method and Constructor extend the class Executable and therefore inherit
the method Executable.getParameters.) However, .class files do not store formal
parameter names by default. To store formal parameter names in a particular .class file,
and thus enable the Reflection API to retrieve formal parameter names, compile the
source file with the -parameters option of the javac compiler. See Obtaining Names
of Method Parameters in the Java Tutorials.

Enhancements in Java SE 7

Binary Literals - In Java SE 7, the integral types (byte, short, int, and long) can also
be expressed using the binary number system. To specify a binary literal, add the
prefix 0b or 0B to the number.

Underscores in Numeric Literals - Any number of underscore characters (_) can
appear anywhere between digits in a numerical literal. This feature enables you, for
example, to separate groups of digits in numeric literals, which can improve the
readability of your code.

Strings in switch Statements - You can use the String class in the expression of
a switch statement.

Type Inference for Generic Instance Creation - You can replace the type arguments
required to invoke the constructor of a generic class with an empty set of type
parameters (<>) as long as the compiler can infer the type arguments from the
context. This pair of angle brackets is informally called the diamond.

Improved Compiler Warnings and Errors When Using Non-Reifiable Formal
Parameters with Varargs Methods - The Java SE 7 complier generates a warning at
the declaration site of a varargs method or constructor with a non-reifiable varargs
formal parameter. Java SE 7 introduces the compiler option -Xlint:varargs and the
annotations @SafeVarargs and @SuppressWarnings({"unchecked", "varargs"}) to
suppress these warnings.

The try-with-resources Statement - The try-with-resources statement is
a try statement that declares one or more resources. A resource is an object that must
be closed after the program is finished with it. The try-with-resources statement
ensures that each resource is closed at the end of the statement. 

Any object that implements the new java.lang.AutoCloseable interface or the java.io.Closeable interface can be used as a resource. The classesjava.io.InputStream, OutputStream, Reader, Writer, java.sql.Connection, Statement, and ResultSet have been retrofitted to implement the AutoCloseable interface and can all be used as resources in a try-with-resources statement.

Catching Multiple Exception Types and Rethrowing Exceptions with Improved
Type Checking - A single catch block can handle more than one type of exception. In
addition, the compiler performs more precise analysis of rethrown exceptions than
earlier releases of Java SE. This enables you to specify more specific exception types in
the throws clause of a method declaration.

Enhancements in Java SE 6
No language changes were introduced in Java SE 6.

Collections Framework Enhancements in Java SE 8
Support for Lambda Expressions, Streams, and Aggregate Operations

The Java Collections Framework has been updated to support lambda expressions, streams,
and aggregate operations. For more information on these topics, see the following pages:

 Enhancements in Java SE 8
 New and Enhanced APIs That Take Advantage of Lambda Expressions and Streams in
 Lambda Expressions (The Java Tutorials)
 Aggregate Operations (The Java Tutorials)
 Collections (The Java Tutorials)

Performance Improvement for HashMaps with Key Collisions
As part of the work for JEP 180, there is a performance improvement for HashMap objects
where there are lots of collisions in the keys. The alternative String hash function added in 7u6 has been removed from JDK 8, along with the jdk.map.althashing.threshold system property. Instead, hash bins containing a large number of colliding keys improve performance by storing their entries in a balanced tree instead of a linked list. This JDK 8 change applies only to HashMap, LinkedHashMap, and ConcurrentHashMap.

In rare situations, this change could introduce a change to the iteration order
of HashMap and HashSet. A particular iteration order is not specified for HashMap objects -
any code that depends on iteration order should be fixed.
Note that, other than removing the feature introduced in 7u6, the java.util.Hashtable class
is not affected. The features added in 7u6 applied to WeakHashMap and Hashtable (and by
extension Properties and Provider) but in JDK 8 these have been removed.

Concurrency Utilities Enhancements in Java SE 8
New classes and interfaces in java.util.concurrent
The java.util.concurrent package contains two new interfaces and four new classes:

 Interface CompletableFuture.AsynchronousCompletionTask: A marker interface
identifying asynchronous tasks produced by async methods.
 Interface CompletionStage: A stage of a possibly asynchronous computation, that 
performs an action or computes a value when another CompletionStage completes.
 Class CompletableFuture: A Future that may be explicitly completed (setting its 
value and status), and may be used as a CompletionStage, supporting dependent
functions and actions that trigger upon its completion.
 Class ConcurrentHashMap.KeySetView: A view of a ConcurrentHashMap as 
a Set of keys, in which additions may optionally be enabled by mapping to a common
 Class CountedCompleter: A ForkJoinTask with a completion action performed when 
triggered and there are no remaining pending actions.
 Class CompletionException: Exception thrown when an error or other exception is
encountered in the course of completing a result or task.

New methods in java.util.concurrent.ConcurrentHashMap
The Collections Framework has undergone a major revision in Java 8 to add aggregate
operations based on the newly added streams facility and lambda expressions. As a result,
the ConcurrentHashMap class introduces over 30 new methods in this release. These include
various forEach methods (forEach, forEachKey, forEachValue, and forEachEntry), search
methods (search, searchKeys, searchValues, and searchEntries) and a large number of
reduction methods (reduce, reduceToDouble, reduceToLong etc.)

Other miscellaneous methods (mappingCount and newKeySet) have been added as well. As
a result of the JDK 8 changes, ConcurrentHashMaps (and classes built from them) are now
more useful as caches. These changes include methods to compute values for keys when
they are not present, plus improved support for scanning (and possibly evicting) entries, as
well as better support for maps with large numbers of elements.

New classes in java.util.concurrent.atomic
Maintaining a single count, sum, etc. that is updated by possibly many threads is a common
scalability problem. This release introduces scalable updatable variable support through a
small set of new classes (DoubleAccumulator,DoubleAdder, LongAccumulator, LongAdder),
which internally employ contention-reduction techniques that provide huge throughput
improvements as compared to Atomic variables. This is made possible by relaxing atomicity
guarantees in a way that is acceptable in most applications.
 DoubleAccumulator: One or more variables that together maintain a running double
value updated using a supplied function.
 DoubleAdder: One or more variables that together maintain an initially zero double sum.
 LongAccumulator: One or more variables that together maintain a running long value
updated using a supplied function.
 LongAdder: One or more variables that together maintain an initially zero long sum.
New methods in java.util.concurrent.ForkJoinPool

A static commonPool() method is now available and appropriate for most applications. The
common pool is used by any ForkJoinTask that is not explicitly submitted to a specified pool.
Using the common pool normally reduces resource usage (its threads are slowly reclaimed
during periods of non-use, and reinstated upon subsequent use). Two new methods
(getCommonPoolParallelism() and commonPool()) have been added, which return the
targeted parallelism level of the common pool, or the common pool instance, respectively.

New class java.util.concurrent.locks.StampedLock
A new StampedLock class adds a capability-based lock with three modes for controlling
read/write access (writing, reading, and optimistic reading). This class also supports
methods that conditionally provide conversions across the three modes.

No comments: