Sunday, April 2, 2017

Java 7 Features

  • Binary Literals  - In Java SE 7, the integral types (byteshortint, 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.
Before:
public void testBinaryIntegralLiterals(){
        int binary = 8;
        if (binary == 8){
            System.out.println(true);
        } else{
            System.out.println(false);
        }
}
Java7:
public void testBinaryIntegralLiterals(){
        int binary = 0b1000; //2^3 = 8
        if (binary == 8){
            System.out.println(true);
        } else{
            System.out.println(false);
        }
}

  • 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.
public void testUnderscoresNumericLiterals() {
    int oneMillion_ = 1_000_000; //new
    int oneMillion = 1000000;
    if (oneMillion_ == oneMillion){
        System.out.println(true);
    } else{
        System.out.println(false);
    }
}

Before:
public void testStringInSwitch(String param){
       final String JAVA5 = "Java 5";
       final String JAVA6 = "Java 6";
       final String JAVA7 = "Java 7";
       if (param.equals(JAVA5)){
           System.out.println(JAVA5);
       } else if (param.equals(JAVA6)){
           System.out.println(JAVA6);
       } else if (param.equals(JAVA7)){
           System.out.println(JAVA7);
       }
   }
Java7:
public void testStringInSwitch(String param){
       final String JAVA5 = "Java 5";
       final String JAVA6 = "Java 6";
       final String JAVA7 = "Java 7";
       switch (param) {
           case JAVA5:
               System.out.println(JAVA5);
               break;
           case JAVA6:
               System.out.println(JAVA6);
               break;
           case JAVA7:
               System.out.println(JAVA7);
               break;
       }
   }

  • Type Inference for Generic Instance Creation (Diamond Operator) - 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.
Before:
public void testDinamond(){
    List list = new ArrayList();
    Map> map = new HashMap>();
}
Java7:
public void testDinamond(){
    List list = new ArrayList<>();
    Map> map = new HashMap<>();
}

  • 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 classes java.io.InputStreamOutputStreamReaderWriterjava.sql.ConnectionStatement, and ResultSet have been retrofitted to implement the AutoCloseable interface and can all be used as resources in a try-with-resources statement.

Before:
public void testTryWithResourcesStatement() throws FileNotFoundException, IOException{
     FileInputStream in = null;
    try {
        in = new FileInputStream("java7.txt");
        System.out.println(in.read());
    } finally {
        if (in != null) {
            in.close();
        }
    }
}
Java 7:
public void testTryWithResourcesStatement() throws FileNotFoundException, IOException{
    try (FileInputStream in = new FileInputStream("java7.txt")) {
        System.out.println(in.read());
    }
}




Before:
public void testMultiCatch(){
     try {
         throw new FileNotFoundException("FileNotFoundException");
     } catch (FileNotFoundException fnfo) {
         fnfo.printStackTrace();
     } catch (IOException ioe) {
         ioe.printStackTrace();
}
Java 7:
public void testMultiCatch(){
    try {
        throw new FileNotFoundException("FileNotFoundException");
    } catch (FileNotFoundException | IOException fnfo) {
        fnfo.printStackTrace();
    }
}




Java 1.6 Features - Collection Framework Enhancements

 
   Java 1.6 provides the better bi-directional collection access on collections framework.

   The following new interfaces are added in this version:

   i) Deque - It is a double ended queue, supporting element insertion and removal at both ends. It extends the Queue interface.
   ii) BlockingDeque - Its inheriting the feature of deque and performs the operations that wait for deque to become non-empty and wait for space to become available in the deque when storing elements.
   iii) NavigableSet - It may be accessed and traversed in either ascending and descending order.
   iv) NavigableMap - It may be accessed and traversed in either ascending and descending key order.
    V) ConcurrentNavigableMap - Its similar to NavigableMap and this interface is part of java.util.concurrent.

    The following classes have been added:

     i) ArrayDeque
    ii) ConcurrentSkiplistSet
   iii) ConcurrentSkipListMap
    iv) LinkedBlockingQueue
     v) AbstractMap.SimpleEntry
    vi) AbstratMap.SimpleImmutableEntry

Other than this Two new methods were added to the Collection Utility classes:

 1. newSetFromMap(Map) -- Create a Set implementaion from Map. There is no IdentitiHashSet class but instead, just use

Set<Object> identityHashSet = Collections.newSetFromMap(new IdentityHashMap<object, Boolean>());

2. asLifoQueue(Deque) - returns a view of a Deque as a Last-in-first-out (Lifo) Queue

The Arrays utility class now has methods copyOf and copyOfRange that can efficiently resize, truncate, or copy subarrays for arrays of all types.
Before:

int[] newArray = new int[newLength];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
After:

int[] newArray = Arrays.copyOf(a, newLength);

Which should you use, abstract classes or interfaces?

Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation. However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods. With interfaces, all fields are automatically public, static, and final, and all methods that you declare or define (as default methods) are public. In addition, you can extend only one class, whether or not it is abstract, whereas you can implement any number of interfaces.
Which should you use, abstract classes or interfaces?
  • Consider using abstract classes if any of these statements apply to your situation:
    • You want to share code among several closely related classes.
    • You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).
    • You want to declare non-static or non-final fields. This enables you to define methods that can access and modify the state of the object to which they belong.
  • Consider using interfaces if any of these statements apply to your situation:
    • You expect that unrelated classes would implement your interface. For example, the interfaces Comparable and Cloneable are implemented by many unrelated classes.
    • You want to specify the behavior of a particular data type, but not concerned about who implements its behavior.
    • You want to take advantage of multiple inheritance of type.
An example of an abstract class in the JDK is AbstractMap, which is part of the Collections Framework. Its subclasses (which include HashMapTreeMap, and ConcurrentHashMap) share many methods (including getputisEmptycontainsKey, and containsValue) that AbstractMap defines.
An example of a class in the JDK that implements several interfaces is HashMap, which implements the interfaces SerializableCloneable, and Map<K, V>. By reading this list of interfaces, you can infer that an instance of HashMap (regardless of the developer or company who implemented the class) can be cloned, is serializable (which means that it can be converted into a byte stream; see the section Serializable Objects), and has the functionality of a map. In addition, the Map<K, V> interface has been enhanced with many default methods such as merge and forEach that older classes that have implemented this interface do not have to define.
Note that many software libraries use both abstract classes and interfaces; the HashMap class implements several interfaces and also extends the abstract class AbstractMap.

Limitation of synchronized keyword in Java

1. Synchronized keyword doesn't allow separate locks for reading and writing. As we know that multiple threads can read without affecting thread-safety of class, synchronized keyword suffer performance due to contention in case of multiple readers and one or few writer.

 2. If one thread is waiting for lock then there is no way to timeout, the thread can wait indefinitely for the lock.
 
3. On a similar note if the thread is waiting for the lock to acquired there is no way to interrupt the thread.
 
All these limitations of synchronized keyword are addressed and resolved by using ReadWriteLock and ReentrantLock in Java 5.

Private and Final Methods in java?

  • private methods cannot be overridden by subclasses
  • final methods cannot be overridden by subclasses
  • final methods allow for faster code when compiled with optimizations on (javac -O)
My questions are:
  1. Why not declare all private methods final as well?
  2. Do most compilers treat private methods as final?
A: As you point out, subclasses may not override private methods by design. Furthermore, the final keyword tells the compiler that subclasses may not override a method regardless of its access level. Since private already implies that a subclass may not override a method, declaring a private method to be final is redundant. Making the declaration won't cause problems, but it won't accomplish anything either, since privates are automatically considered final.
Well, the practice of declaring all private methods final will have one side effect. Any novice Java programmer who encounters your code will assimilate your usage of private final, thinking that privates must be declared in that manner. So, you'll be able to judge who has and who has not been in contact with your code. It might prove an interesting exercise.
So, to answer question 1, there is no need to declare private members final.
As for question 2, an optimizing compiler and JVM can take advantage of privatemethods and final methods. Since subclasses may not override those types, there is no need to do dynamic binding at runtime. Subclasses will never override the method, so the runtime will always know what method to call without searching up the inheritance hierarchy. During compilation an optimizing compiler may even choose to inline all private and final methods to improve performance.
So, to answer question 2, yes, all compilers will treat private methods as final. The compiler will not allow any private method to be overridden. Likewise, all compilers will prevent subclasses from overriding final methods.
A more interesting question: Will all compilers optimize finals and privates so that they are inline? The short answer is no. Optimization behavior will be dependent on the compiler and its settings.

When and where to use the Singleton Pattern?

Singletons are used in situations where we need access to a single set of data throughout
an application. 

For example, application configuration data and reusable data caches are
commonly implemented using singletons. Singletons may also be used to coordinate access

to shared resources, such as coordinating write access to a file.

Singleton pattern is used for logging, drivers objects, caching and thread pool.(in log4j,Hibernate we are using the this pattern)

Saturday, April 1, 2017

Why SerialVersionUID?

      When you serialize an object using Serialization mechanism (by implementing Serializable interface), there is a possibility that you may face versioning issues and because of these versioning issues, you will not be able to deserialize the object. Thats not a good thing. But first, what is this versioning issue that is troubling your serialization process?
Well, lets say you created a class, instantiated it, and wrote it out to an object stream. That flattened object sits in the file system for some time. Meanwhile, you update the class file, perhaps adding a new field. Now try to read the flattened object. hmmmm.. An exception "java.io.InvalidClassException" will be thrown. You dont understand where it went wrong because the changes in the class seem perfectly fine for you.
What is serialVersionUID?
Before we start discussing about the solution for this problem, lets first see what is actually causing this problem? Why should any change in a serialized class throw InvalidClassException? During object serialization, the default Java serialization mechanism writes the metadata about the object, which includes the class name, field names and types, and superclass. All this information is stored as part of the serialized object. When you deserialize the object, this information is read to reconsitute the object. But to perform the deserialization, the object needs to be identified first and this will be done by serialVersionUID. So everytime an object is serialized the java serialization mechanism automatically computes a hash value using ObjectStreamClass’s computeSerialVersionUID() method by passing the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value, the serialVersionUID.
Now when the serilaized object is retrieved, the JVM first evaluates the serialVersionUID of the serialized class and compares the serialVersionUID value with the one of the object. If the sserialVersionUID values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.

The above issue not only occurs when the object is flattened and saved but also when the object is flattened and sent to other JVMs when you implement RMI. Lets assume you have a client/server environment where client is using SUN's JVM in windows while server is using JRockit in Linux. Client sends a serializable class with default generated serialVersionUID (e.g 123L) to server over socket, while server may generate a different serialVersionUID (e.g 124L) during deserialization process, and raise an unexpected InvalidClassExceptions. Since the default serialVersionUID computation is highly sensitive to class details and may vary from different JVM implementation, an unexpected InvalidClassExceptions will result here.
What's the solution for this versioning issue?
The solution is very simple. Instead of relying on the JVM to generate the serialVersionUID, you explicitly mention (generate) the serialVersionUID in your class. The syntax is:

private final static long serialVersionUID = <integer value>

Yes, its a static, private variable in the class. Once you define the serialVersionUID in your class explicitly, you dont need to update it until and unless you make the incompatible changes. Look at the example below that explains the issue and importance of maintaining serialVersionUID.
class TestSUID implements Serializable {
    private static final long serialVersionUID = 1L;

    private int someId;

    public TestSUID (int someId) {
        this.someId = someId;
    }

    public int getSomeId() {
        return someId;
    }
}
 

public class SUIDTester {
    public static void main(String args[]) throws Exception {
        File file = new File("temp.ser");
        FileOutputStream fos = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        TestSUID writeSUID = new TestSUID(1);
        oos.writeObject(writeSUID);
        oos.close();

        FileInputStream fis = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(fis);

        TestSUID readSUID = (TestSUID) ois.readObject();
        System.out.println("someId : " + readSUID.getSomeId());
        ois.close();
    }
}
 
In this example, we have created a Serializable class with serialVersionUID = 1L and saved the "some id" value in the "temp.ser" file. Now change the serialVersionUID value of "TestSUID" class to 2L and try to just read the "temp.ser" file. It will throw "InvalidClassException". The reason is the version change and exactly this is the reason for maintaining the version.
Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
serialVersionUID = 1, local class serialVersionUID = 2

When should you update serialVersionUID?
Adding serialVersinUID manually to the class does not mean that it should never be updated and never need not be updated. There is no need to update the serialVersionUID if the change in the class is compatible but it should be updated if the change is incompatible. What are compatible and incompatible changes? A compatible change is a change that does not affect the contract between the class and the callers.

The compatible changes to a class are handled as follows:
  • Adding fields - When the class being reconstituted has a field that does not occur in the stream, that field in the object will be initialized to the default value for its type. If class-specific initialization is needed, the class may provide a readObject method that can initialize the field to nondefault values.
  • Adding classes - The stream will contain the type hierarchy of each object in the stream. Comparing this hierarchy in the stream with the current class can detect additional classes. Since there is no information in the stream from which to initialize the object, the class’s fields will be initialized to the default values.
  • Removing classes - Comparing the class hierarchy in the stream with that of the current class can detect that a class has been deleted. In this case, the fields and objects corresponding to that class are read from the stream. Primitive fields are discarded, but the objects referenced by the deleted class are created, since they may be referred to later in the stream. They will be garbage-collected when the stream is garbage-collected or reset.

  • Adding writeObject/readObject methods - If the version reading the stream has these methods then readObject is expected, as usual, to read the required data written to the stream by the default serialization. It should call defaultReadObject first before reading any optional data. The writeObject method is expected as usual to call defaultWriteObject to write the required data and then may write optional data.
  • Removing writeObject/readObject methods - If the class reading the stream does not have these methods, the required data will be read by default serialization, and the optional data will be discarded.
  • Adding java.io.Serializable - This is equivalent to adding types. There will be no values in the stream for this class so its fields will be initialized to default values. The support for subclassing nonserializable classes requires that the class’s supertype have a no-arg constructor and the class itself will be initialized to default values. If the no-arg constructor is not available, the InvalidClassException is thrown.
  • Changing the access to a field - The access modifiers public, package, protected, and private have no effect on the ability of serialization to assign values to the fields.
  • Changing a field from static to nonstatic or transient to nontransient - When relying on default serialization to compute the serializable fields, this change is equivalent to adding a field to the class. The new field will be written to the stream but earlier classes will ignore the value since serialization will not assign values to static or transient fields.

Incompatible changes to classes are those changes for which the guarantee of interoperability cannot be maintained. The incompatible changes that may occur while evolving a class are:
  • Deleting fields - If a field is deleted in a class, the stream written will not contain its value. When the stream is read by an earlier class, the value of the field will be set to the default value because no value is available in the stream. However, this default value may adversely impair the ability of the earlier version to fulfill its contract.
  • Moving classes up or down the hierarchy - This cannot be allowed since the data in the stream appears in the wrong sequence.
  • Changing a nonstatic field to static or a nontransient field to transient - When relying on default serialization, this change is equivalent to deleting a field from the class. This version of the class will not write that data to the stream, so it will not be available to be read by earlier versions of the class. As when deleting a field, the field of the earlier version will be initialized to the default value, which can cause the class to fail in unexpected ways.
  • Changing the declared type of a primitive field - Each version of the class writes the data with its declared type. Earlier versions of the class attempting to read the field will fail because the type of the data in the stream does not match the type of the field.
  • Changing the writeObject or readObject method so that it no longer writes or reads the default field data or changing it so that it attempts to write it or read it when the previous version did not. The default field data must consistently either appear or not appear in the stream.
  • Changing a class from Serializable to Externalizable or visa-versa is an incompatible change since the stream will contain data that is incompatible with the implementation in the available class.
  • Removing either Serializable or Externalizable is an incompatible change since when written it will no longer supply the fields needed by older versions of the class.
  • Adding the writeReplace or readResolve method to a class is incompatible if the behavior would produce an object that is incompatible with any older version of the class.

How to generate a serialVersionUID?
There are two ways to generate the serialVersionUID.
  • Go to commanline and type "serialver <>. SerialVersionUID wil be generated. Copy, paste the same into your class.
    In Windows, generate serialVersionUID using the JDK's graphical tool like so : use Control Panel | System | Environment to set the classpath to the correct directory
    run serialver -show from the command line
    point the tool to the class file including the package, for example, finance.stock.Account - without the .class
    (here are the serialver docs for both Win and Unix)
  • One way is through Eclipse IDE. After you implement Serializable interface and save the class, eclipse will show a warning asking you to add the serialVersionUID and it provides you the option to generate it or use the default one. Click on the link to generate the serialVersionUID and it will generate it for you and adds it to the class.

Finally few guidelines for serialVersionUID :


  • always include it as a field, for example: "private static final long serialVersionUID = 7526472295622776147L; " include this field even in the first version of the class, as a reminder of its importance
  • do not change the value of this field in future versions, unless you are knowingly making changes to the class which will render it incompatible with old serialized objects
  • new versions of Serializable classes may or may not be able to read old serialized objects; it depends upon the nature of the change; provide a pointer to Sun's guidelines for what constitutes a compatible change, as a convenience to future maintainers