New Features in Java 7.0 – Part 1

This article discusses the new features that are available in Java 7.0. Java 7.0 comes with bunch of new features – language level changes as well as API level changes and this article concentrates on the new API features such as Cache API, New Date and Time API and New IO 2 as well as the language level changes in the form of Super packages. The readers are assumed that they are more familiar with the Java 5.0 language level changes such as Generics and Annotations. This article covers few of the new features in Java 7.0 and the remaining set of new features will be covered in the next article. It is likely that the APIs may undergo changes before the formal release of Java 7.0 happens. You can read Java 7.0 Articles.

New features in Java 7.0

also read:

The following new features will be discussed in detail in this article.

  • Cache API
  • Date and Time API
  • New IO2
  • Super Packages

Cache API

The Cache API provides the mechanism for storing and retrieving the objects. The API also provides a way to plug-in user defined Cache objects. The Cache API is relatively small and this section discusses the core classes and the interfaces available in the Cache API.

Cache Manager

The Cache Manager stands as the entry point for using Cache API. An instance of the CacheManager can be obtained using the following code,

CacheManager manager = CacheManager.getInstance();

This method will return a singleton object of type CacheManager. The cache manager also provides methods for registering and deregistering cache objects. Have a look at the following code,

Cache permanentCache = .... // an implementation of a permanent cache
manager.registerCache("PERM_CACHE", permanentCache);

Cache and CacheFactory

The API provides plug-in capabilities of custom implementation through the help of Cache and the CacheFactory interfaces. The Cache interface extends the Map interface so the put, get and iteration methods that are available in the map can be directly used. It is also possible to remove the objects in the cache that are no longer needed through the Cache.evict() method. CacheFactory is a service provider API and it provides a factory method for creating a Cache object from a map of properties.

CacheManager manager = CacheManager.getInstance();
CacheFactory factory = manager.getCacheFactory();

Map cacheProperties = ....;
Cache cacheObject = factory.createCache(cacheProperties);

An object is no longer needed in the cache if the expiration time set for the object expires and that’s where the CacheEntry object comes in.

CacheEntry

The interface provides certain useful information and operations that are applicable for an object in a cache such as the last access time, last update time, creation time, expiration time etc. Note that this interface directly extends Map.Entry interface. It is possible to obtain an instance of this object from the object’s key,

Cache permanentCache = .... // an implementation of a permanent cache
permanentCache.put("MYSTR", someStrObject);

CacheEntry entry = cache.getCacheEntry("MYSTR");

Cache Events

It is also possible to attach listeners to cache object when objects are stored, removed, loaded and evicted from the cache. An implementation of a cache listener could be,

SimpleCacheListener.java

class SimpleCacheListener implements CacheListener
{
    void onClear() {}

	void onEvict(Object key) {}

	void onLoad(Object key) {}

	void onPut(Object key) {}

	void onRemove(Object key) {}
}

This cache listener can be added to cache for receiving any events notification through the following code,

Cache cacheObject = ...;
cacheObject.addListener(new SimpleCacheListener());

Date and Time API in Java 7.0

Problems in Existing API

Even though there are APIs in Java in the form of java.util.Date, java.util.Calendar, java.sql.Date etc., there still seems to be problems in the usage and the representation of the date, time and its related entities from the developer’s point of view. As a very simple example, consider the following code snippet,

Date marchSixth2000 = new Date(2000, 2, 6, 0, 0, 0);

One would expect that for the representation of 6th of march 2000, the object is created. However, since in Java APIs the time starts from 1900, the year should be actually (2000 – 1900) and not 2000. There is no support in Java Date APIs till date for the representation of entities like interval, duration, periods, date without time, time without date etc. There are also other problems in the API similar to this as well as the representation of year, month, day etc., using primitive types.

Terminologies

Before getting into the new additions and enhancements, let us look into the basic terminologies available in the new API.

Instant

An instant represents an instantaneous point in a time line and this is always with respect to a well defined fixed time point that starts from 1970/01/01. The instant, which is represented by javax.time.Instant can be created as follows,

Long epochSeconds = ....;
Instant i = Instant.instant(epochSeconds);

An epoch represents a well known fixed point of time in a time line and the standard epoch in Java starts from 1970/01/01. So, in the above code, the epochSeconds represents the number of seconds starting from 1970/01/01.

Interval

An interval represents the interval between two instants. Flexible factory methods are available for the creation of Interval objects. An interval is represented by javax.time.InstantInterval class.

Instant begin = Instant.instant(...);
Instant end = Instant.instant(...);

InstantInterval interval = InstantInterval.intervalBetween(begin, end);

Duration

The entity Duration refers to the duration between two instants on the time line. It is represented via javax.time.Duration. Since duration represents the interval of two instants, a duration object can be created as follows,

Instant begin = Instant.instant(...);
Instant end = Instant.instant(...);

InstantInterval interval = InstantInterval.intervalBetween(begin, end);
Duration duration = Duration.durationOf(interval);

Date and Time API

The date and time portion of the java.util.Date object which were earlier represented using primitive data types have been refactored to use appropriate types. Following are the classes involved,

  • LocalDate
  • LocalTime
  • LocalDateTime

Consider the following date representation using ISO 8601 standard,

01/01/2000 05:09:03

The above representation is a combination of Date and Time, hence we have separate classes for representing the date and time which are javax.time.LocalDate and javax.time.LocalTime respectively. There also exists a class that represents the combination of date and time, which is LocalDateTime.

The date portion comprises of 3 more sub-components which are the year, the month of the year and the date of the month. The following code shows the construction of these sub components.

Year year2005 = Year.isoYear(2005);
MonthOfYear aprilMonth = MonthOfYear.APRIL;
DayOfMonth twenty = DayOfMonth.dayOfMonth(20);

LocalDate localDate = LocalDate.date(year2005, aprilMonth, twenty);

Similarly the time portion comprises of hour of the day, minute of the hour, second of the minute and the nano second of the second and the following code just shows that.

HourOfDay fivePM = HourOfDay.hourOfDay(AmPmOfDay.PM, 4);
MinuteOfHour tenthMinute = MinuteOfHour.minuteOfHour(9);
SecondOfMinute fivteenthSecond = SecondOfMinute.secondOfMinute(14);

LocalTime localTime = LocalTime.time(fivePM, tenthMinute, fiveteenthSecond);

LocalDateTime dateAndTime = LocalDateTime.dateTime(year2005, aprilMonth, twenty,
         fivePM, tenthMinute, fiveteenthSecond);

FileSystem in Java 7.0

The new Java IO adds more capabilities to the underlying file system for handling and manipulating files through the use of a new interface called FileSystem. This interface provides a handle to the file system and it provides several utility and factory methods for accessing the files. Since the implementation of a file system will be different for different operating systems, FileSytemProvider objects provide implementation for defining a file system.

However, the local file system (also referred to as the platform file system or the default file system) will also exist in a system irrespective of the type of the operating system, and a reference to the default file system can be obtained through the following code,

FileSystem defaultFS = FileSystem.getDefault();

FileSystem objects are opened whenever a new instance of the same is created and will be kept open until the method FileSystem.close() is called. The method FileSystem.isOpen() will return false after the FileSystem.close() method is called. It is also possible for the implementation of a file system to provide read-only access alone to the file system. In that case, the following method will return true;

Boolean readOnly = fileSystem.isReadOnly()

PathReference

PathReferences are objects that are used to locate physical files in the file system. These objects usually take the relative or the absolute path strings for locating the file. The following code can be used to create the PathReference object,

PathReference pf = PathReference.from("C:\\test");

It is also possible to create files and directories by passing in an array of attributes using PathReference.createFile() and the PathReference.createDirectory() methods

PathReference also provides methods for copying and moving files and directories. The following code copies the directory “C:\\test” to “D:\\test”. If there is a directory by the name ‘test’ in ‘D:\\” then the destination directory is replaced.

PathReference source = PathReference.from("C:\\test");
PathReference destination = PathReference.from("D:\\test");

source.copyTo(destination, CopyFlags.REPLACE_EXISTING);

Asynchronous IO operations

Reading/writing operations which are typically synchronous at this point of time are now going to get enhanced asynchronously. APIs have been updated to achieve this. The asynchronous mode of reading/writing is applicable not only for files but also for sockets.

Consider the following piece of code,

PathReference pf = PathReference.from("C:\\myFile.txt");
AsynchronousFileChannel channel = AsynchronousFileChannel.open(pf);

ByteBuffer readContents[] = ...;
IoFuture result = channel.read(readContents, new ReadCompletionHandler();

// Other follows here

And here is the code for ReadCompletionHandler.

class ReadCompletionHandler implements CompletionHandler
{
    public void completed(IoFuture result)
    {
        try
        {
            int bytesRead = result.getNow();
        }
        catch (IOException x)
        {
            // error handling
        }
    }
}

Super Packages in Java 7.0

A package in Java provides logical way of organization of classes and interfaces. They also help to prevent class name conflicts since it is possible to have the same class names but in different packages. One major area of obvious restriction seen in a package is the lack of access control definitions between the packages. Assume that we have two packages com.myorg.comp1 and com.myorg.comp2. All public classes/interfaces in comp1 package can be accessed by the classes/interfaces in the types that are available in comp2.

Super packages can be thought of as container of packages and sub-packages with defined access control restrictions. All related packages can be grouped into a super package and types are accessible to the outside world or to another super package only when they are exported explicitly.

Example for Super Packages

Let us assume that we have two packages representing the model and UI portion of some imaginary project called myApp namely com. myorg.myApp.ui and com.myorg.myApp.model. Let us also assume that we have identified different forms of UI like the Swing UI, Html UI etc., and we wish to create two new sub-packages namely com.myorg.myApp.ui.swing and com.myorg.myApp.ui.html. Similarly we want to define to two model hierarchies: one for the Swing UI and the other for the Html UI.

In this case, we can define two super package constructs as follows,

super-package.java

superpackage com.myorg.myApp.ui
{
	member package com.myorg.myApp.ui.swing;

	member package com.myorg.myApp.ui.html;
}

super-package.java

superpackage com.myorg.myApp.model
{
	member package com.myorg.myApp.model.swing;

	member package com.myorg.myApp.model.html;
}

The above example code shows how a super package is defined by adding two member packages. It is possible for a super package to contain another super package as one of its members. In such a case, the super package that is defined as a member is called a nested super package. Let us now define a super package for the myApp project itself.

super-package.java

super package superpackage com.myorg.myApp
{
	member superpackage com.myorg.myApp.ui;

	member superpackage com.myorg.myApp.model;
}

Imagine that within the swing’s model package we have various types such as SEmployee, SDepartment and SOrganization and for the html’s model package we have the types such as HEmployee, HDepartment and HOrganization. Let us also assume that only the types SEmployee and SDepartment are going to get used by the swing UI components and all the types within the html’s model package are going to be used by the html’s UI components. In this case, we have modify the definition of the model superpackage as follows,

super-package.java

superpackage com.myorg.myApp.model
{
	member package com.myorg.myApp.model.swing;

	member package com.myorg.myApp.model.html;

	export com.myorg.myApp.model.swing.SEmployee;
	export com.myorg.myApp.model.swing.SDepartment;

	export package com.myorg.myApp.model.html;
}

Note that we have exported only the SEmployee and the SDepartment types for the swing’s model package, and all the public types have been exported for the html’s model package.

The definition of a super package has to be written in a java file called super-package.java and this file should reside in the super package directory. During the stage of compilation, the compiler will process this super-package.java file and will generate a .superpackage file.

Conclusion

This article started with the discussion of the advent of the new Cache Manager API that provides the pluggable implementations for defining new cache instances. This was followed by discussion of the various problems that are there in the existing Date and Time APIs and illustrated the enhancements in the new Date and Time APIs. The new perspective that has been defined for the FileSytem, PathReference and the asynchronous support to IO operations were also dealt in detail. Finally the concepts of super package along with access control restrictions, as well as code examples were also discussed.

Comments

comments

About Krishna Srinivasan

He is Founder and Chief Editor of JavaBeat. He has more than 8+ years of experience on developing Web applications. He writes about Spring, DOJO, JSF, Hibernate and many other emerging technologies in this blog.

Speak Your Mind

*

Close
Please support the site
By clicking any of these buttons you help our site to get better