1. Quick Glance at the Upcoming Features in JDK 7
1. Switch with Strings value.
2. Automatic Resource Management (ARM)
try ( FileOutputStream fos = new FileOutputStream(file); InputStream is =
url.openStream()
)
3. Dynamic Invokation
In Java 7, we’ll see a new feature, the JSR 292. This JSR add new method invocation
mode : invokedynamic. With that new bytecode keyword, we can call method only
known at runtime.
This JSR only impact the bytecode not the language. But with Java 7 we’ll see a new
package java.dyn that use this new functionality. That package will improve the
performances of Java reflection and mainly the performances of the others languages
that run in the JVM.
(http://www.baptiste-wicht.com/2010/04/java-7-more-dynamics/ )
4. ThreadLocalRandom
A really simple but useful enhancement is the add of the ThreadLocalRandom class.
This class is a random number generator linked to the current Thread. It seems that if
you use this generator from two different thread, you will have two different random
generators. The generator is initialized with a generated seed that you cannot modify
-
(setSeed() throws anUnsupportedOperationException).
You can use that class like that :
long l = ThreadLocalRandom.current().nextLong(22L);
If you always use this form, you have the guarantee that the random generator will
never be shared between two threads. Moreover, this new class provide methods to
generate a bounded numbers. By example, to generate a pseudo-random number
between 10, inclusive and 33, exclusive, you can type :
int i = ThreadLocalRandom.current().nextInt(10, 33);
5. java.utils.Objects
public void setFoo(Foo foo){
this.foo = Objects.nonNull(foo);
}
2. public void setBar(Bar bar){
this.foo = Objects.nonNull(bar, "bar cannot be null");
}
public class Bar {
private Foo foo;
private Bar parent;
@Override
public int hashCode(){
int result = 17;
result = 31 * result + (foo == null ? 0 : foo.hashCode());
result = 31 * result + (parent == null ? 0 : parent.hashCode());
return result;
}
}
With Java 7, we only have to do the following :
public class Bar {
private Foo foo;
private Bar parent;
@Override
public int hashCode(){
return Objects.hash(foo, parent);
}
}
6. Deep Equals
boolean equals(Object a, Object b) : Return true if the two arguments are null or they
are both not null and a.equals(b) return true, otherwise false.
3. • boolean deepEquals(Object a, Object b) : Almost the same as the first method
except that if both a and b are arrays, the equality is evaluated using
Arrays.deepEquals method.
7. Better Exception Handling :
} catch (FirstException ex) {
logger.error(ex);
throw ex;
} catch (SecondException ex) {
logger.error(ex);
throw ex;
}
So now, with that new feature, you can do :
} catch (FirstException | SecondException ex) {
logger.error(ex);
throw ex;
}
8. Allow -overriding static methods- new List interface
List strings = new ArrayList();
//...
Collections.reverse(strings);
>>>
public interface List extends Collection {
...
extension void reverse() default Collections.reverse;
}
So you can do :
List strings = new ArrayList();
//...
strings.reverse();
4. 9. New File API
(http://download.oracle.com/javase/tutorial/essential/io/legacy.html#mapping )
Prior to the JDK7 release, the java.io.File class was the mechanism used for
file I/O, but it had several drawbacks.
• Many methods didn't throw exceptions when they failed, so it was
impossible to obtain a useful error message. For example, if a file
deletion failed, the program would receive a "delete fail" but
wouldn't know if it was because the file didn't exist, the user didn't
have permissions, or there was some other problem.
• The rename method didn't work consistently across platforms.
• There was no real support for symbolic links.
• More support for metadata was desired, such as file permissions, file
owner, and other security attributes.
• Accessing file metadata was inefficient.
• Many of the File methods didn't scale. Requesting a large directory
listing over a server could result in a hang. Large directories could
also cause memory resource problems, resulting in a denial of
service.
• It was not possible to write reliable code that could recursively walk
a file tree and respond appropriately if there were circular symbolic
links.
10. Asynchronous I/O
Arguably this id the most important feature in jdk 7 !!
Here go the details from the following website ....
http://www.baptiste-wicht.com/2010/04/java-7-new-io-features-asynchronous-
operations-multicasting-random-access-with-jsr-203-nio-2/
"... The new Asynchronous I/O API. Its name indicate all the purpose of this new
features, indeed enable Asynchronous I/O operations.This new channels
provide asynchronous operations for both sockets and files.
Of course, all that operations are non-blocking, but there is also blocking operations
that you can do with all the asynchronous channels.
All the asynchronous I/O operations have one of two forms :
• The first one returns a java.util.concurrent.Future that represent the pending
result. You can use that Future to wait for the I/O operations to finish.
5. • The second one is created using a CompletionHandler. That handler is invoked
when the operation is has completed, like callbacks systems.
So here are the examples of the two forms :
The first form, using Future :
AsynchronousFileChannel channel
= AsynchronousFileChannel.open(Paths.get("Path to file"));
ByteBuffer buffer = ByteBuffer.allocate(capacity);
Future result = channel.read(buffer, 100); //Read capacity bytes from the file starting
at position 100
boolean done = result.isDone(); //Indicate if the result is already terminated
You can also wait for completion :
int bytesRead = result.get();
Or wait with a timeout :
int bytesRead = result.get(10, TimeUnit.SECONDS); //Wait at most 10 seconds on
the result
The second form, using CompletionHandler :
Future result = channel.read(buffer, 100, null, new CompletionHandler(){
public void completed(Integer result, Object attachement){
//Compute the result
}
public void failed(Throwable exception, Object attachement){
//Answer to the fail
}
});
As you can see, you can give an attachement to the operation. This attachement is
given to the CompletionHandler at the end of the operation. You can give null as
attachement with no problem. But you can pass anything you want, like the
Connection for a AsynchronousSocketChannel or the ByteBuffer for our read :
Future result = channel.read(buffer, 100, buffer, new CompletionHandler(){
public void completed(Integer result, ByteBuffer buffer){
//Compute the result
6. }
public void failed(Throwable exception, ByteBuffer buffer){
//Answer to the fail
}
});
And as you can see, the form with the CompletionHandle gives also you a Future
element representing the pending result, so you can merge the two forms.
Here, are all the asynchronous channels available in NIO.2 :
• AsynchronousFileChannel : An asynchronous channel for reading and writing
from and to a file. This channel has no global positions, so each read/write
operations needs a position to operate. You can access concurrently to different
parts of the file using different threads. You have to specify the options
(READ, WRITE, but not APPEND) when you open this channel.
• AsynchronousSocketChannel : A simple asynchronous channel to a Socket.
The connect, read/write and scatter/gather methods are all asynchronous. The
read/write method supports timeouts.
• AsynchronousServerSocketChannel : An asynchronous channel to a
ServerSocket. The accept() method is asynchronous and the
CompletionHandler is called when a connection has been accepted. The result
of this kind of connection is an AsynchronousSocketChannel.
• AsynchronousDatagramChannel :
An channel to datagram-oriented socket. The read/write (connected) and
receive/send (unconnected) methods are asynchronous.
"
References :
http://tech.puredanger.com/java7/
http://www.baptiste-wicht.com/2010/04/java-7-updates-project-coin/