27 May 2013

How Many Ways We Can Create Threads In Java

In java there are only 2 ways of creating threads. How ever since java1.5 there is one another way to invoke a Thread. The following shows how we can create threads in java.

First Method:-

A class can extend Thread class and overrides the run method of the Thread class.

Example:- 

 public class Murali extends Thread{
     public void run(){
     ==do something here==
    }
  }//class ends here.
Murali a=new Murali();
a.start();

Second Method:-

Writing a custom class which implements Runnable interface and pass this class to the Thread constructor.

Example:-      

 public class Car implements Runnable{
   public void run(){
    ==do something here==
   }
  }

Thread a=new Thread(new Car());
a.start();

Second method is good than first method because only one class can be extended and if you have extended Thread class no other class can be extended.
Since java1.5:-

How ever since java1.5 there is another way to invoke a thread. That is by “ExecutorService”. All these classes are from the “java.util.concurrent” package. There are various ways to create a “ExecutorService” using “Executors” factory class. The following is one of the way to create “ExecutorService”..

ExecutorService es= Executors.newSingleThreadExecutor();
RunnableImpl r = new RunnableImpl();
Future fu=es.submit(r);

using “ExecutorService” methods we can submit eighter Runnable or Callable to the service for execution.

How ever this cannot be said as the new way to create a Thread. It is because ExecutorService internally uses “ThreadFactory” class to create a new thread which internally uses eighter first or second method. So we have to say that there are only two ways to create threads but there is a new way in java1.5 to invoke a thread but not to create a Thread.

How “Thread.join()” works in Java

The join is the instance method in the Thread class. So many people get confused of the function of join. So thought to document the functionality of it. The join functionality awaits the thread to die. Here is how it works with example.

Example:-

public class ThreadJoin {

 public static void main(String[] args)throws Exception {
  Thread a=new Thread(new Mur(),"1");
  Thread b=new Thread(new Mur(),"2");
 
  a.start();
  a.join();
  b.start();
 
  System.out.println("End Of Main Thread");

 }

 private static class Mur implements Runnable{
  public void run() {
              for (int x = 1; x <= 10; x++) {
                       System.out.println("this is thread "
                                       + Thread.currentThread().getName());
                      }
  }
 }//end of the static inner class.
}//end of the main class.

Normally the thread that runs the main method is called main thread. So when main thread starts the other threads it does not stop executing. It starts the other threads and still continues it’s execution. Main thread finishes it’s execution and at the end it waits for the other threads that it created to die. Once the other threads it created dies then the main thread also dies.


Now How Does Join Makes Difference:-

The thread that executes the join on another thread waits (without moving to next instruction) until the thread on which the join is called dies.

In the example the main thread started a new thread by executing start method on Thread object “a” (a.start();). So now the thread “a” (Thread a=new Thread(new Mur(),"1")) starts executing as an individual light weight process. The main thread moves on and executes the next statement that is “a.join();”. The moment that it executes join on thread “a” it goes into a waiting mode, This means it stops executing the next instructions. The main thread invoked “join” (a.join();)on another thread (that is on thread object “a”) so it stops executing and waits until the other thread on which the join is called dies. Once the other thread dies the main thread resumes and starts executing the next instructions.

So the thing that has to be understood is, any thread that invokes join on another thread waits until the thread on which join is called finishes it’s execution.

The Output of the above stated example when “a.join()” is commented:-

this is thread 2
this is thread 1
this is thread 1
End Of Main Thread
this is thread 1
this is thread 2
this is thread 2
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 2
this is thread 1
this is thread 1
this is thread 1
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2


The Output of the above stated example with “a.join()”:-

this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
End Of Main Thread
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2

Thread Safety In Java

Thread safety is avoiding thread interference.Thread interference is two or more threads executing a set of operations on the same data concurrently.This causes problem. To avoid this we should make sure that one thread runs at a time and not to allow another thread to run on the same data until it is finish.

This can be achieved in java by synchronization and from java1.5 there is a new way of doing this, that is Atomic actions also called as non blocking algorithms. 

synchronization can be achieved in 2 ways. one is synchronizing the methods and the other is using synchronized blocks.

synchronizing methods:-
synchronized keyword can only be used in front of the methods. The following is the example.

Example:-

public class SynchMethEx {

            private int counter;

           public synchronized void increase(){
                // do some operations and increse the counter
               //to the desired value
           }

          public synchronized void decrease(){
             // do some operations and decrease the counter
             //to the desired value
         }

        public synchronized int getCounter(){
             return counter;
        }
}

in this when a thread enters into one synchronized method of the class it achieves the intrinsic lock of that object so that any other thread cannot enter any of the synchronized methods of that class until the thread comes out of the synchronized method it entered. Once the thread comes out of the synchronized method and before it enters into another synchronized the lock on that object will be released so there is a chance that another thread can attain the lock and perform a synchronized method.

synchronizing the whole method will be a bottleneck for performance. Instead only synchronize the block which needs thread safety.

synchronized blocks:-

The synchronized blocks improves the performance by only synchronizing the block of code which is necessary. The following is the example.

Example:-

public class SynchBlock {

 public static void main(String[] args)throws Exception {
 
  Thread b=new Thread(new Kir(ThreadSync.class),"2");
  Thread c=new Thread(new Kir(ThreadSync.class),"3");
  Thread d=new Thread(new Kir(ThreadSync.class),"4");
 
 
  b.start();
  c.start();
  d.start();

 }

 
 private static class Kir implements Runnable{

         private Object obj;

        public Kir(Object obj){
            this.obj=obj;
       }

        public void run(){
             synchronized(obj){
                  int i=0;
                  while(true){
                     System.out.println("Thread"+Thread.currentThread().getName()+"@"+i);
                      if(i==100)break;
                     i++;
                 }//end of the while loop.
             }//end of the synchronized block.
       }//end of run method.
 }//end of the inner class.

}//end of the main class.

Before the thread enters into the synchronized block it has to obtain intrinsic lock on the object specified in the in the parentheses of the block definition(in the above example the lock on the object it has to attain is “obj”). Once it achieves the lock it will be able to execute the synchronized block. Once the thread is out of the synchronized block the lock on that particular object will be released so that another thread can attain a lock and can execute the synchronized block.

so the above two methods achieve thread safety but there is a problem. when one thread attained intrinsic lock on the object, The other threads that try to attain lock on the same object move to the runnable state and has to be rescheduled and also need to compete for the lock with the other threads who are waiting for the lock on the same object.

So java1.5 came with a solution called Atomic actions or Non Blocking Algorithms.  

Atomic Actions or Non Blocking Algorithms(Since java1.5):-

In concurrent programming an operation (or set of operations) is atomic, linearizable, indivisible or uninterruptible if it appears to the rest of the system to occur instantaneously.Atomicity is a guarantee of isolation from concurrent process. Additionally, atomic operations commonly have a succeed or fail definition — they either successfully change the state of the system, or have no apparent effect.

In programming, an atomic action is one that effectively happens all at once. An atomic action cannot stop in the middle: it either happens completely, or it doesn't happen at all. No side effects of an atomic action are visible until the action is complete.

An atomic action has to happen all at once or none. It is not that thread which is executing the atomic operation need not be in a running state until it completes the action. The atomic action ensures that the effects of it or seen only after the complete execution and if this detects the thread interference it does nothing. It ensures thread safety. It appears like all happened at once

For example the following are the steps involved in atomic operation:-

 Take the value from the shared variable.
  increment the value by one
  set the value back again to the shared variable.
 so the operation has to look like the complete operation had happened at once or instantaneously. so it follows the following algorithm.
 Take the value of the shared variable into another local variable(int i=j).
Add one to it and assign it to another variable(int k=i+1)
Now lock the shared variable(may be at hardware level) and check whether the shared variable still holds the value that it took at the beginning of the operation.
If it is the same then set the increased value(k) to the shared variable (j)  and release the lock so that other threads can perform operation on shared variable.
If it is not the same (suppose while these operations are happening another thread got it’s turn and changed the shared variable value) then nothing happens, it does not change the shared variable value and also releases the lock making the variable available to other threads for operating on it.
So the whole operation looks like it happened at once or not happened at all.

This is how it avoids thread interference and ensures thread safety.

Atomicity is commonly enforced by mutual exclusion, whether at the hardware level building on a cache coherency protocol, or the software level using semaphores or locks. Thus, an atomic operation does not actually occur instantaneously. The benefit comes from the appearance: the system behaves as if each operation occurred instantly, separated by pauses.

In computer science, compare-and-swap (CAS) is an atomic instruction used in multithreading to achieve synchronization. It compares the contents of a memory location to a given value and, only if they are the same, modifies the contents of that memory location to a given new value. This is done as a single atomic operation. The atomicity guarantees that the new value is calculated based on up-to-date information; if the value had been updated by another thread in the meantime, the write would fail. The result of the operation must indicate whether it performed the substitution; this can be done either with a simple Boolean response (this variant is often called compare-and-set), or by returning the value read from the memory location (not the value written to it).

In java
Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
Reads and writes are atomic for all variables declared volatile (including long and double variables).

Since java1.5 Some of the classes in the package “java.util.concurrent” provide atomic methods that do not rely on synchronization.

Atomic variables:-

The “java.util.concurrent.atomic” package defines classes that support atomic operations on single variables. All classes have get and set methods that work like reads and writes on volatile variables. That is, a set has a happens-before relationship with any subsequent get on the same variable. The atomic compareAndSet method also has these memory consistency features, as do the simple atomic arithmetic methods that apply to integer atomic variables.

Example:-

import java.util.concurrent.atomic.AtomicInteger;

class AtomicCounter {
    private AtomicInteger c = new AtomicInteger(0);

    public void increment() {
        c.incrementAndGet(); //This is atomic operation. Internally uses CAS.
    }

    public void decrement() {
        c.decrementAndGet(); // this is atomic. Internally uses CAS.
    }

    public int value() {
        return c.get();
    }

}

The Atomic variables also contain CAS methods which perform Atomic operations.

Threads In Brief(java)

 when you want to concurrent tasks threads are the way in java to do it. Thread is a lightweight process which is part of the process. The threads can share memory but they run on their own stack. Every thread has a lifecycle. It will be in different states throughout its life cycle.

Thread Life Cycle:-




New State:-

when Thread object is created (Thread as=new Thread(new RunnableImpl)) it will be in new state. In this state the thread is not alive. From new state they move to runnable state.

Runnable State:-

From new state it moves to runnable state when start() method is called on the thread. Once the start() method is called on the thread,  the thread moves to runnable state. In this state the thread is ready to run and is waiting for the thread scheduler to give him a chance to run. In this state the thread is alive. when thread scheduler gives the thread a chance to run then it moves to running state.

Running State:-

Once the thread scheduler gives a chance to a thread that is in runnable state to run then it moves to running state. This is state that does some action. In this state the thread starts executing its task, that means it starts executing the threads “run()” method. As long as it is in this state it keeps executing until it dies. From this state thread can move back to runnable state or it moves to blocked state or it moves to dead state.

Blocked state:-

If the static method yield() is invoked on the thread the thread moves from running state to runnable state. If the static method sleep() is invoked on the thread then it moves to blocking state from running state for a certain period of time. If method wait() is called in the synchronized code then also the thread moves from running state to blocked state. If Thread has to wait for some input then also it moves to blocked state from running state. The thread is alive in this state.

Once the threads are out of blocked state they move to runnable state.

Dead State:-

If the thread finishes its execution, that means if it completes the “run()” method then it moves to a dead state. Once the thread is dead that cannot be started again but it can be accessed as a normal java object.

Thread priorities are not guaranteed. we can set the priorities but it is not guaranteed that the the thread scheduler gives high priority thread a chance to run immediately. It can pick up any thread. Thread scheduler is platform dependent. It may use different algorithms like “Round Robin” or “Time Slicing” for implementation.

Important Methods In Thread Class:-

 Thread.sleep(long millis):-

when this static method is called the currently executing thread moves to blocked state, i mean it sleeps for at least the specified amount of time. If this is called inside the synchronized code the thread goes to sleep without releasing the lock. It does not release the lock until it finishes the synchronized code.

Thread.yield():-

when this static method is called the currently executing thread moves to runnable state from running state.

Thread.join():-

The thread which executes “join()” method on another thread object will stop executing until the other thread on which “join()” is called finishes its execution, i mean until it is dead.

Thread.interrupt():-

Sends signal to thread to interrupt execution.

Inter Thread Communication:-

Threads communicate with each other by using the following methods that are declared inside the class “Object”. All these methods can be called only inside the synchronized code. Before calling this methods the thread has to attain intrinsic lock on that particular object.

 wait()
notify()
notifyAll()

wait():-

This causes the thread to move to waiting state(blocked state) until another thread notifies it. The thread releases the lock before it enters to blocked state. Here the thread enters to a pool of waiting threads on that particular object.

notiy():-

When this method is called on a particular object, it wakes up a single thread from the pool of threads waiting on that particular object. Choosing the thread is arbitrary.

notifyAll():-

When this method is called on a particular object, it wakes up all the threads in the pool waiting on that particular object.

Example for Inter communication:-

class Q {
   int n;
   boolean valueSet = false;
   synchronized int get() {
      if(!valueSet)
      try {
         wait();
      } catch(InterruptedException e) {
         System.out.println("InterruptedException caught");
      }
      System.out.println("Got: " + n);
      valueSet = false;
      notify();
      return n;
   }

   synchronized void put(int n) {
      if(valueSet)
      try {
         wait();
      } catch(InterruptedException e) {
         System.out.println("InterruptedException caught");
      }
      this.n = n;
      valueSet = true;
      System.out.println("Put: " + n);
      notify();
   }
}// end of class Q

class Producer implements Runnable {
   Q q;
   Producer(Q q) {
      this.q = q;
      new Thread(this, "Producer").start();
   }

   public void run() {
      int i = 0;
      while(true) {
         q.put(i++);
      }
   }
}

class Consumer implements Runnable {
    Q q;
    Consumer(Q q) {
       this.q = q;
       new Thread(this, "Consumer").start();
    }
    public void run() {
       while(true) {
       q.get();
    }
  }
}
public class PCFixed {

   public static void main(String args[]) {
      Q q = new Q();
      new Producer(q);
      new Consumer(q);
      System.out.println("Press Control-C to stop.");
   }
}

Guarded Blocks:-
 a block begins by polling a condition that must be true before the block can proceed.
For Example:-
public void guardedJoy() {
    // Simple loop guard. Wastes
    // processor time. Don't do this!
    while(!joy) {}
    System.out.println("Joy has been achieved!");
    // some more instructions goes here.
}

In the above the complete method is guarded by a polling condition. It makes sure the method does not get executed until the condition is met. Until some other thread sets the “joy” value to “false” the loop keeps polling. This also can be improved by Inter Thread Communication(wait, notify).

Thread Liveness:-

The notion that your program will not lock up and eventually do something useful is called the liveness property.

There are a number of reasons why a multi-threaded program will fail liveness:

      Deadlock
      Starvation and Live Lock

Deadlock:-

Both the threads wait for each other to release the resource for further processing is called deadlock.
Example:-

public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s" + "  has bowed to me!%n",
            this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s" + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse = new Friend("Alphonse");
        final Friend gaston =  new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}

Deadlocks can be avoided by using Explicit locks which are introduced as part of the “java.util.concurrent.locks” package from java1.5.

Explicit Locks:-

Lock objects work very much like the implicit locks used by synchronized code. As with implicit locks, only one thread can own a Lock object at a time. Lock objects also support a wait/notify mechanism, through their associated Condition objects.

The biggest advantage of Lock objects over implicit locks is their ability to back out of an attempt to acquire a lock. The tryLock method backs out if the lock is not available immediately or before a timeout expires (if specified). The lockInterruptibly method backs out if another thread sends an interrupt before the lock is acquired.

solving deadlock using explicit locks:-

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;

public class Safelock {
    static class Friend {
        private final String name;
        private final Lock lock = new ReentrantLock();

        public Friend(String name) {
            this.name = name;
        }

        public String getName() {
            return this.name;
        }

        public boolean impendingBow(Friend bower) {
            Boolean myLock = false;
            Boolean yourLock = false;
            try {
                myLock = lock.tryLock();
                yourLock = bower.lock.tryLock();
            } finally {
                if (! (myLock && yourLock)) {
                    if (myLock) {
                        lock.unlock();
                    }
                    if (yourLock) {
                        bower.lock.unlock();
                    }
                }
            }
            return myLock && yourLock;
        }
           
        public void bow(Friend bower) {
            if (impendingBow(bower)) {
                try {
                    System.out.format("%s: %s has" + " bowed to me!%n", this.name, bower.getName());
                    bower.bowBack(this);
                } finally {
                    lock.unlock();
                    bower.lock.unlock();
                }
            } else {
                System.out.format("%s: %s started"
                    + " to bow to me, but saw that"
                    + " I was already bowing to"
                    + " him.%n",
                    this.name, bower.getName());
            }
        }

        public void bowBack(Friend bower) {
            System.out.format("%s: %s has" +
                " bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    static class BowLoop implements Runnable {
        private Friend bower;
        private Friend bowee;

        public BowLoop(Friend bower, Friend bowee) {
            this.bower = bower;
            this.bowee = bowee;
        }
   
        public void run() {
            Random random = new Random();
            for (;;) {
                try {
                    Thread.sleep(random.nextInt(10));
                } catch (InterruptedException e) {}
                bowee.bow(bower);
            }
        }
    }
           

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new BowLoop(alphonse, gaston)).start();
        new Thread(new BowLoop(gaston, alphonse)).start();
    }
}

Starvation:-

If the currently executing thread keeps on executing synchronized methods on the object and if it does block the other threads waiting for monitor lock on the same object for longer time is called starvation.

 Immutable Objects:-

 An object is considered immutable if its state cannot change after it is constructed. Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.
 Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

Thread Safety:-

This can be achieved by avoiding thread interference. This can be done by synchronizing methods, synchronizing blocks and Atomic actions.

The java.util.concurrent package includes a number of additions to the Java Collections Framework which can be safely used in concurrent applications.

Annotations(java)


 Annotations are first introduced in java1.5. Annotation mean “a crucial explanatory note” added to anything. These are more powerful than java comments, javadoc comments.

Annotations have a number of uses, among them:

 Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.

Compiler-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.

Runtime processing — Some annotations are available to be examined at runtime.

Using annotations, we are able to add metadata information to our source code – build or deployment information, configuration properties, compilation behavior or quality checks.

Annotations can be retained at source code level, class level and runtime level. If the retention policy is specified as “source code” then the annotations will only be used by the compiler and they will not present in the class files. If the retention policy is “class” then the annotations will be present in class files but will not be used by VM. If the retention policy is “runtime” then they are also available at runtime which means the VM loads them.

Annotation is a kind of interface. 

Annotation Types have some differences compared to regular interfaces:
 Only primitives, strings, enums and arrays of them are allowed. Note that as Objects in general are not allowed, arrays of arrays are not allowed in Annotation Types (every array is an object).
The annotation elements are defined with a syntax very similar to that of methods, but keep in mind that modifiers and parameters are not allowed.
Default values are defined using the default keyword followed by the value that will be a literal, an array initializer or an enum value.

 All the annotations by default extends “java.lang.annotation.Annotation”. we are not manually allowed to extend an interface in annotations. This happens automatically like all classes extends “java.lang.Object” class by default.

Here while declaring annotation the Interface keyword is preceded by “@”. The declaration of Annotation is as follows.


public @interface Complexity {

    Level value(); // The return type Level is an Enum.
    String date();
    int currentRevision() default 1;
    String lastModified() default "N/A";
    String lastModifiedBy() default "N/A";
    // Note use of array
    String[] reviewers();

}

Single Value Annotations:-

There is a chance that an annotation can have only one element. In such a case that element should be named value.

To make the information in @Complexity appear in Javadoc-generated documentation, you must annotate the @Complexity definition itself with the@Documented annotation:

@Documented
@interface Complexity {

   // Annotation element definitions
 
}

Annotations can be applied to a program's declarations of classes, fields, methods, and other program elements.

@Author(
   name = "Benjamin Franklin",
   date = "3/27/2003"
)
class MyClass() { }
or
@SuppressWarnings(value = "unchecked")
void myMethod() { }

If there is just one element named "value," then the name may be omitted, as in:
@SuppressWarnings("unchecked")
void myMethod() { }

Also, if an annotation has no elements, the parentheses may be omitted, as in:
@Override
void mySuperMethod() { }

Annotations Used by the Compiler

There are three annotation types that are predefined by the language specification itself: 

@Deprecated, @Override, and @SuppressWarnings.

@Deprecated—the @Deprecated annotation indicates that the marked element is deprecated and should no longer be used. The compiler generates a warning whenever a program uses a method, class, or field with the @Deprecated annotation. When an element is deprecated, it should also be documented using the Javadoc @deprecated tag, as shown in the following example. The use of the "@" symbol in both Javadoc comments and in annotations is not coincidental — they are related conceptually. Also, note that the Javadoc tag starts with a lowercase "d" and the annotation starts with an uppercase "D".

  // Javadoc comment follows
    /**
     * @deprecated
     * explanation of why it
     * was deprecated
     */
    @Deprecated
    static void deprecatedMethod() { }
}

@Override—the @Override annotation informs the compiler that the element is meant to override an element declared in a superclass (overriding methods will be discussed in the the lesson titled "Interfaces and Inheritance").
  // mark method as a superclass method
   // that has been overridden
   @Override
   int overriddenMethod() { }

While it's not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with @Override fails to correctly override a method in one of its superclasses, the compiler generates an error.

@SuppressWarnings—the @SuppressWarnings annotation tells the compiler to suppress specific warnings that it would otherwise generate. In the example below, a deprecated method is used and the compiler would normally generate a warning. In this case, however, the annotation causes the warning to be suppressed.

  // use a deprecated method and tell
   // compiler not to generate a warning
   @SuppressWarnings("deprecation")
    void useDeprecatedMethod() {
        // deprecation warning
        // - suppressed
        objectOne.deprecatedMethod();
    }
Every compiler warning belongs to a category. The Java Language Specification lists two categories:

"deprecation" and "unchecked." The "unchecked" warning can occur when interfacing with legacy code written before the advent of generics (discussed in the lesson titled "Generics"). To suppress more than one category of warnings, use the following syntax:

@SuppressWarnings({"unchecked", "deprecation"})



The JDK comes with some annotations that are used to modify the behavior of the Annotation Types that we are defining:

@Documented: Indicates that the marked Annotation Type should be documented by Javadoc each time it is found in an annotated element.

@Inherited: Indicates that the marked Annotation Type is inherited by subclasses. This way, if the marked annotation is not present in a subclass it inherits the annotation in the superclass, if present. Only applies to class inheritance and not to interface implementations.

@Retention: Indicates how long the marked Annotation Type will be retained. Possible values are those of enum RetentionPolicy: CLASS (default – included in class files but not accessible at run-time), SOURCE (discarded by the compiler when the class file is created) and RUNTIME (available at run-time).

@Target: Indicates the element types to which the marked Annotation Type is applicable. Possible values are those of enum ElementType: ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER and TYPE.

Processing Annotations:-

The Annotation Processor API

When Annotations were first introduced in Java 5, the Annotation Processor API was not mature or standardized. A standalone tool named apt, the Annotation Processor Tool, was needed to process annotations, and the Mirror API, used by apt to write custom processors, was distributed in com.sun.mirror packages.
Starting with Java 6, Annotation Processors were standardized through JSR 269 (2), incorporated into the standard libraries and the tool apt seamlessly integrated with the Java Compiler Tool, javac.

We can process the annotations using customs processors and can perform desired actions based on the annotations.

Anybody who writes custom annotation processor has to implement the interface “javax.annotation.processing.Processor” but java provides an abstract class which implements this interface making the developer job easy by providing implementation to most common methods. The abstract class name is “javax.annotation.processing.AbstractProcessor”. This class has an abstract method


“public abstract boolean process(Set<? extends TypeElement> annotations,    RoundEnvironment roundEnv)”

Parameters:
annotations - the annotation types requested to be processed
roundEnv - environment for information about the current and prior round

The annotation processing may happen in several rounds. RoundEnvironment provides the current round information.

All the classes, methods,variables that are annotated are treated as elements. The “RoundEnvironment.getElementsAnnotatedWith” method returns the annotated things as Elements. The Elements could be of kind annotation, class, constructor,enum, enum constant, field and so on.

The following is the example of a processor which process “Complexity” annotation to write a new source code file from the existing.

Enum class used in this example:-

public enum Level {

 SIMPLE, MEDIUM, COMPLEX;
}

Annotation used in this example:-

public @interface Complexity {
   Level value();
}

Class that will be processed in this example:-

@Complexity(Level.SIMPLE)
public class Person {

 @Complexity(Level.MEDIUM)
 public void move(){
 
 }

 @Complexity(Level.COMPLEX)
 public void drive(){
 
 }
}

The Processor which process the annotation:-

import java.io.BufferedWriter;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileObject;

/**
 * @author Muralidhar Yaragalla
 *
 */
@SupportedAnnotationTypes("annotate.Complexity")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class ComplexityProcessor extends AbstractProcessor{

 @Override
 public boolean process(Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv){
 
           for(Element elm:roundEnv.getElementsAnnotatedWith(Complexity.class)){
           //processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,elm.getSimpleName());
                   if (elm.getKind() == ElementKind.CLASS) {
                           TypeElement classElement = (TypeElement) elm;
                           PackageElement packageElement = (PackageElement) classElement.getEnclosingElement();
                           try{
                                    JavaFileObject jfo = processingEnv.getFiler().createSourceFile(classElement.getQualifiedName() + "info");

                                  BufferedWriter bw = new BufferedWriter(jfo.openWriter());
                                  bw.append("package ");
                                  bw.append(packageElement.getQualifiedName());
                                  bw.append(";");
                                  bw.newLine();
                                  bw.newLine();
                                 bw.flush();
                                bw.close();
                           }catch(Exception e){
       
                           }
                 }//end of if
        }//end of for
 
       return true;
 
     }

}

How this entire process works:-

The class files of the custom processor and its dependencies has to be packed in a jar file and this jar file should be in the classpath before compiling the source files(declared with annotations). Then when the compiler(javac) is invoked on the source files. It starts executing the Processor whenever it finds the source files with the registered annotation to that Processor. The Processor process the source files when compilation itself.

How to package the Processor:-

The jar file should contain a “META-INF” folder. Inside “META-INF” folder there should be a folder with name “services”. Inside “services” folder a file with name “javax.annotation.processing.Processor” has to be created. Inside this file the processors(Fully qualified name of the processor) have to be specified. One Processor in one line.

                                      

Remote Method Invocation (RMI)


 RMI is all about invoking methods of an object that resides in another JVM. So from one JVM we can invoke methods of an object that is in another JVM. The another JVM might be on the same machine or it could be somewhere else on the network. This is the basis for EJB.

In this the server (which has very high configuration and speed and rich in hardware) exposes the remote objects via RMI Registry. Clients fetches the remote object reference via a proxy object and executes the methods on remote machine and gets the return type given by the remote method to the client’s JVM and uses it for further processing.

The following is in detail:-

What Server does?:-

The server creates a remote object and exports it to the RMI environment, which means it creates a stub or proxy for the remote object and the stub will be binded in the RMI Registry with a name.

What Client does?-

It locates (connects) the RMI registry on the remote machine(server) and  performs a lookup operation with the name of the object. The lookup operations will download the stub class of the remote object and its state by which it will be able to create the same object in the clients machine and returns the stub object. With the help of this stub object we will be able to execute the remote object's methods and can obtain the result of the remote method which means client obtains the  return type of the remote method and this result will be used for further processing in the client.

Here on client and server machine when an object has to be downloaded first the class and the state  of that object will be downloaded which help rebuilding the same object with the same behaviour. The remote object always resides on the server and will never be downloaded by any client. The client only downloads the proxy or stub.

                       
                                 


Creating Remote Objects:-

First we have to create a remote interface by which we expose methods to the network. The remote interface is created by extending the “java.rmi.Remote”. Now the interface which extends the “java.rmi.Remote” interface have to declare methods that have to be exposed to the network. All the methods in the remote interface should throw “java.rmi.RemoteException”.



Example:-

package rmi.common;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface TaskEngine extends Remote{

 Boolean executeTask(Task t)throws RemoteException;

}

The return type or parameters of the remote method should be of primitive data types or remote objects or serializable classes.

Once we create the remote interface we need to provide implementation for that. So a class which implements the remote interface should be created. This class may contain additional methods other than the ones declared in the remote interface but these additional methods are local and will not be exposed to network(other JVM).

Example Implementation:-

package rmi.server;

import java.rmi.RemoteException;

import rmi.common.Task;
import rmi.common.TaskEngine;

public class TaskEngineImpl implements TaskEngine{

 @Override
 public Boolean executeTask(Task t)throws RemoteException {
           return t.execute();
 }
 
}

Server program:-

The server program will bind the remote object in the RMI Registry. The server program keeps waiting to listen to clients.. As long as the remote object is not unbound or as long as the client holds the reference to the remote object the remote object will not be garbage collected.

Example:-
package rmi.server;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import rmi.common.TaskEngine;

public class Server {

    public static void main(String[]args)throws RemoteException{
          if (System.getSecurityManager() == null) {
                   System.setSecurityManager(new SecurityManager());
           }
           String name="taskExe";
           TaskEngine te=new TaskEngineImpl();
            TaskEngine stub =(TaskEngine) UnicastRemoteObject.exportObject(te, 0);
            Registry registry = LocateRegistry.getRegistry();
            registry.rebind(name, stub);
            System.out.println("TaskEngine bound");
    }
}

There are few things to be kept in mind when writing server program.

 The first thing is to set the security manager. If security manager is not set the files from the client system will not be downloaded as they can harm the computer by accessing the resources on the server computer. So the security manager has to be set.

remote object should be created and should be assigned to a variable of type remote interface.
The remote object needs to be passed to the “UnicastRemoteObject.exportObject(te, 0)” so that this method can create a stub and returns that. The stub should be held by the variable of remote interface data type. It also exports the required classes to the RMI environment.

The second argument in the “UnicastRemoteObject.exportObject(te, 0)” , an int, specifies which TCP port to use to listen for incoming remote invocation requests for the object. It is common to use the value zero, which specifies the use of an anonymous port. The actual port will then be chosen at runtime by RMI or the underlying operating system. However, a non-zero value can also be used to specify a specific port to use for listening. Once the exportObject invocation has returned successfully, the TaskEngineImpl remote object is ready to process incoming remote invocations.

using  “LocateRegistry.getRegistry()”  when no arguments passed we can get the RMI registry running on the same machine.

The methods of RMIRegistry such as bind, rebind, unbind can perform operations only on the registry running on the same machine. when these methods are invoked from a remote machine on the servers registry they don’t have any effect. so clients cannot bind or unbind the objects on server.

Client Program:-

package rmi.client;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import rmi.common.Task;
import rmi.common.TaskEngine;

public class Client {
        public static void main(String[] args)throws Exception {
                 if (System.getSecurityManager() == null) {
                       System.setSecurityManager(new SecurityManager());
                }
                Registry registry = LocateRegistry.getRegistry("localhost");
                TaskEngine te = (TaskEngine) registry.lookup("taskExe");
                 Task t=new HugeProcess();
                 if(te.executeTask(t)){
                       System.out.println("executed the task successfully on remote machine");
                  }

       }
}

Points that need to be observed when writing Client:-

 The first thing is to set the security manager if not already there on the system.
“registry.lookup("taskExe")” downloads the stub class, state of the stub object that is bound in the registry on the remote computer and creates the stub object and returns it to the variable of data type remote interface. Stub also implements all the interfaces implemented by remote object.

when “Task t=new HugeProcess()” invoked the Task object is created and when it is passed to the stub objects method as parameter, the server downloads the “HugeProcess” class, state and creates the task object back again on the server and executes the remote method on the server and the return value is passed to the client back again. Client used the return value of the remote method in further processing.

Remote Interface , any custom classes or interfaces provided as arguments and return types  to the remote methods should be made available to both client and server. In our example “TaskEngine”, “Task” should be made available to both server and client. The “Task” implementation “HugeProcess” should be only in the client, It does not need to be on the server.

Running Server and Client:-

First we need to create security policy files for client and server which are required by the security manager.

The client security policy for example “client.policy” has to be on the classpath of the clients machine and this policy file should grant all the permissions to the local code (classes which are not downloaded).

client policy file:-

grant codeBase "file:D:/workspace/example/bin/" {
    permission java.security.AllPermission;
};

Server policy file for example “server.policy” should be on the classpath of the servers machine as the server program security manager needs it.

servers policy:-

grant codeBase "file:D:/workspace/example/bin/" {
    permission java.security.AllPermission;
};

In both the policy files the “codeBase” should refer to the root folder where your class files are residing.

Once the policy files are set we should start the RMI registry on the servers machine. just type “rmiregistry” in the command prompt and that would run the register.


Running Server:- 

java -Djava.rmi.server.codebase=file:/D:/workspace/example/bin/
        -Djava.rmi.server.hostname=localhost
        -Djava.security.policy=server.policy
         rmi.server.Server

The above java command defines the following system properties:

 The java.rmi.server.codebase property specifies the location, a codebase URL, from which the definitions for classes originating from this server can be downloaded. If the codebase specifies a directory hierarchy (as opposed to a JAR file), you must include a trailing slash at the end of the codebase URL.

The java.rmi.server.hostname property specifies the host name or address to put in the stubs for remote objects exported in this Java virtual machine. This value is the host name or address used by clients when they attempt to communicate remote method invocations. By default, the RMI implementation uses the server's IP address as indicated by the java.net.InetAddress.getLocalHost API. However, sometimes, this address is not appropriate for all clients and a fully qualified host name would be more effective. To ensure that RMI uses a host name (or IP address) for the server that is routable from all potential clients, set thejava.rmi.server.hostname property.

The java.security.policy property is used to specify the policy file that contains the permissions you intend to grant.

Running Client:-

java     -Djava.rmi.server.codebase=file:D:/workspace/example/bin
           -Djava.security.policy=client.policy
            rmi.client.Client

The above java command defines the following system properties:

The location where the client serves its classes (the “HugeProcess” class) by using the java.rmi.server.codebase property

The java.security.policy property, which is used to specify the security policy file that contains the permissions you intend to grant to various pieces of code.

Difference between Byte Code and Class file


 when we compile a java source file it will be converted to a class file. The classes or interfaces written in the source file will be converted to bytecode and will be stored in the class file. The class file does not only contain byte code. It also contains some additional information which is useful to the compiler and virtual machine to compile and interpret the byte code.

For example when generic class is compiled the generic class will be converted to bytecode and will be stored in the class file. The byte code does not contain any information about generics but the class file which is generated from the source file does contain information about generics. This information is useful to the compiler when compiling other source files.

For Example:-

The source file which contains generic class:-
public class Person<T>{
   
       public T add(T a){
               System.out.println("happy");
       }
}


Generated Byte Code for the above class when compiled which is stored in the class file:-

public class Person{

         public Object add(Object a){
                    System.out.println("happy");
         }
}

The byte code will be stored in the class file and also the class file contains some additional information which is required by the compiler and virtual machine such as information about generics which are not really the part of Byte Code.

Generally VM need some additional information, which is usually stored at the top of the file (the file "header"), to know how to load and interpret the binary data in the file. Such header information could contain the generics details.

The process of erasing generics while compilation is called type erasure which is not very important to know in this context.

Generics in Detail (Java)


If we use Generics in a class that is called as Generic Class. A generic type is a generic class or interface that is parameterized over types.

In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parametersused in method declarations, type parameters provide a way for you to re-use the same code with different inputs. The difference is that the inputs to formal parameters are values, while the inputs to type parameters are types.

Generics add stability to your code by making more of your bugs detectable at compile time.By using generics, programmers can implement generic algorithms that work on collections of different types, can be customized, and are type safe and easier to read. Heavy usage of Generics can cause disaster. It does not make any difference at runtime but it makes the code not readable and not easy to understand.

Code that uses generics has many benefits over non-generic code:
 Stronger type checks at compile time.
 A Java compiler applies strong type checking to generic code and issues errors if the          code violates type safety. Fixing compile-time errors is easier than fixing runtime errors, which can be difficult to find.
 Elimination of casts.

 The following code snippet without generics requires casting:

List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);

When re-written to use generics, the code does not require casting:

List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0);   // no cast

Enabling programmers to implement generic algorithms.
By using generics, programmers can implement generic algorithms that work on collections of different types, can be customized, and are type safe and easier to read.


Why name Generics:-

Generics generalizes the behaviour of the class. By using generic algorithms we can generalize the behaviour of the class or interface.

The following code is without Generics:-

public class Person{

    private String obj;

  public void add(String a){
        obj=a;
  }

  public String get(){
  return obj;
  }
}

In the above code we can store only a “String” object or an object which extends String (String is a final class which cannot be extended) with “add” method and can retrieve “String” object with “get” method. So it’s scope is limited to store a string object.

The following is code with Generics:-

public class Person<T>{

    private T obj;

  public void add(T a){
       obj=a;
  }

  public T get(){
  return obj;
  }
}

By the above code we have generalized the behaviour of the class. Here the scope is not limited to a single type. Here we can pass any type of object and can be retrieved without typecasting the object as compiler adds the typecasting code to the Byte Code. For example the class can be initialized as Person<String> as=new Person<String>() or it can be Person<xxx> as=new Person<xxx>(). It can be initialized with any type(class, Interface).

This is the reason these are called Generics.

How can we make a class Generic class:-

We can make a class Generic by adding type parameters to a class.  Type parameters are different from normal parameters.

Formal or Normal Parameters:-

public class Person{

  private String obj;

  public void add(String a){
       obj=a;
  }

}
In the above code the method “ public void add(String a)” contains a single parameter that is “a”. The type of the parameter “a” is String. When this method is invoked from a different class we pass an argument to the parameter “a”. The argument is an value (Object). We pass an object of type String as an argument to the parameter “a”. Once the parameter is defined that can used inside the method. Parameter is nothing but a variable declared in the method definition. Parameters have to be defined first so that they can be referred inside the method body.  The parameters will be defined inside the parentheses just after the constructor or method name.

Type Parameters:-

Type parameters are the variables defined in angle brackets. The variable name can be anything(t, ta, type, xxx). It is like any normal variable in java but by convention to differentiate between normal parameter and type parameter a single uppercase letter is used as the parameter and it does not have any data type. Normal parameter have a data type when defined but type parameter does not have a data type when defined. for normal parameters we send objects as arguments but for type parameters we pass data types(name of the class) as arguments. Type parameters are defined inside the angle brackets just after the class name or just before the methods return type.
any number of variables can be defined separated by comma. As we are passing types as arguments to this parameters they are called type parameters. Once the type parameters are defined they can be referenced elsewhere in the class.

Example:-

public class Person<T>{

    private T obj;

  public void add(T a){
  obj=a;
  }
}

In the above class T is defined after the class name in angle brackets and has been referenced throughout the class.

How to understand Generics:-

Generic class:-
public class Person<T>{

    private T obj;

  public void add(T a){
  obj=a;
  }
           
             public T get(){
  return obj;
  }

}

when we pass arguments to the type parameters it is to say to the compiler how the objects should be casted (to what data type they should be casted) rather than what data type objects the type parameter references can hold.

for example when the person class is created “Person<String> per=new Person<String>()” . This is to say to the compiler that all the objects passed to the references of type parameters should be casted to String but the type parameter references can hold any object of String class or any class object that extends String (Note :- String is a final class and cannot be extended) but when we retrieve the object from the type parameter reference variable it will only be type casted to string .

The following declarations will be incorrect:-

String cannot be extended but think that StringEx extends String. Now StringEx is the subclass of String. So “Person<String> per=new Person<StringEx>()” is incorrect. why because as i said when we pass the arguments to the type parameters it is just to say to the compiler to what type the object that is passed to the type parameter reference variable has to casted when necessary.  so when compiler encounters the above statement it will get confused whether the object that is passed to type parameter reference variable has to be casted to “String” or “StringEx” as every “StringEx” object can be “String” but Every “String” object cannot be “StringEx”.  So the correct way to define the above statement is “Person<String> per=new Person<String>()” or “Person<StringEx> per = new Person<StringEx>()”.

But when we are passing data to the type parameter reference variable “a” in “add” method of person class it can be a “String” or “StringEx” object but finally when we obtain the stored object using “get” method in Person class the return type will be “String” no matter whether it is a subclass object of String class.

Now in java 1.7 as they found it is meaningless to pass the same data type argument on both side of the assignment operator they have introduced “Diamond”. With this the Person class object can be created as follows.
                    Person<String> per= new Person<>()
The above code is equivalent to
                    Person<String> per=new Person<String>()

Raw Type:-

When generic class object is created without passing arguments to type parameters then they are called raw types.

For example if the Person class object is created as “Person per=new Person()” this is called raw type as we have ignored type parameters without passing arguments to it. You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type.


Generic Methods:-

Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.

The syntax for a generic method includes a type parameter, inside angle brackets, and appears before the method's return type. Despite of the class having type parameters defined the methods as well also can have its own type parameters defined and can be used within the method. The scope of these defined parameter types only to that particular method.

Example:-

public class Util {
    // Generic static method
    public static <W> W compare(W as) {
        return as;
    }
}

In the above class the static method is defined with generics.  The <W> just before the return type says that a generic <W> is defined in the method “compare” and can be used in the “compare” method. So if the compare method is invoked with String object then the return type also will be the String object as the return type we specified is “W”. So after defined it has been referenced in two places. one is as parameter type and the second one is as return type.

Bounded Type Parameters:-

There may be times when you want to restrict the types that can be used as type arguments in a parameterized type. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for.

To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound, which in this example is Number. Note that, in this context, extends is used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).

Examples:-

public <U extends Number> void inspect(U u){
        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());
    }


In the above example the method uses a bounded type parameter. In the type parameter definition it is defined as “<U extends Number>” that means the type parameter variable “u” can accept only objects that extends “Number”.

public class NaturalNumber<T extends Integer> {

    private T n;

    public NaturalNumber(T n)  { this.n = n; }

    public boolean isEven() {
        return n.intValue() % 2 == 0;
    }
}

In the above example The class “NaturalNumber” can accept only type arguments which extends Integer.

Multiple Bounds:-

The preceding example illustrates the use of a type parameter with a single bound, but a type parameter can have multiple bounds:
<T extends B1 & B2 & B3>
In this example The data type that is passed to type parameter “T” should implement B1 and B2 and B3. If one of the bounds is a class, it must be specified first.

 Generic Constructors:-

 class MyClass<X> {
  <T> MyClass(T t) {
    // ...
  }
}

Invocation of the above class could be “new MyClass<Integer>("xxx")”.

Wild Cards:-

In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific). The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.

To declare an upper-bounded wildcard, use the wildcard character ('?'), followed by the extends keyword, followed by its upper bound. Note that, in this context, extendsis used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).

Example:-

public static void process(List<? extends Foo> list) {
    for (Foo elem : list) {
        // ...
    }
}

The upper bounded wildcard, <? extends Foo>, where Foo is any type, matches Foo and any subtype of Foo. The process method can access the list elements as typeFoo.

Unbounded wild cards:-

The unbounded wildcard type is specified using the wildcard character (?), for example, List<?>. This is called a list of unknown type. There are two scenarios where an unbounded wildcard is a useful approach:

If you are writing a method that can be implemented using functionality provided in the Object class.
When the code is using methods in the generic class that don't depend on the type parameter. For example, List.size or List.clear. In fact, Class<?> is so often used because most of the methods in Class<T> do not depend on T.


Example:-

public static void printList(List<?> list) {
    for (Object elem: list)
        System.out.print(elem + " ");
    System.out.println();
}

In the above example the parameter “list” can accept any thing such as ArrayList that contains Strings or Integers or any objects.

The code “List<?> list=new ArrayList<String>()” is valid statement but we cannot add any objects to arraylist. If we try to add an object to arraylist compiler error will be thrown because compiler cannot infer what kind of object is safe to add as <?> denotes unknown type.

Lower Bounded Wildcards:-

A lower bounded wildcard restricts the unknown type to be a specific type or a super type of that type.  A lower bounded wildcard is expressed using the wildcard character ('?'), following by the super keyword, followed by its lower bound: <? super A>

Example:-

public static void addNumbers(List<? super Integer> list) {
    for (int i = 1; i <= 10; i++) {
        list.add(i);
    }
}
In the above method the parameter “list” can accept eighter an Integer object or the object of any of its super class. so passing an ArrayList which holds Integers or ArrayList that holds Number objects or ArrayList that holds objects of Object class can be passed to the parameter “list”.

Wildcard capture and Helper Methods:-

In some cases, the compiler infers the type of a wildcard. For example, a list may be defined as List<?> but, when evaluating an expression, the compiler infers a particular type from the code. This scenario is known as wildcard capture.

The WildcardError example produces a capture error when compiled:

import java.util.List;

public class WildcardError {

    void foo(List<?> i) {
        i.set(0, i.get(0));
    }
}

The above code produces compiler error when an object is being inserted to list as compiler cannot infer what object it can add safely to the list as <?> says unknown.

So there is a work around for this kind of problems. we can write additional methods which are called “Helper Methods” to solve this kind of problems.

public class WildcardFixed {

    void foo(List<?> i) {
        fooHelper(i);
    }

    // Helper method created so that the wildcard can be captured
    // through type inference.
    private <T> void fooHelper(List<T> l) {
        l.set(0, l.get(0));
    }
}

Type Erasure:-

Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. Generics will be removed by the compiler when converting source to bytecode. However the class files contain byte code and also some additional information such as Generics which are useful for the compiler and VM for further processing.



To implement generics, the Java compiler applies type erasure to:

Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
Insert type casts if necessary to preserve type safety.
Generate bridge methods to preserve polymorphism in extended generic types.
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.

Generic class in source file:-

public class Person<T>{
 
       public T add(T a){
               System.out.println("happy");
               return a;
       }
}

The same above class in Byte Code:-
public class Person{
 
       public Object add(Object a){
               System.out.println("happy");
               return a;
       }
}

Restrictions on Generics:-

 cannot instanciate Geniric types with primitive types.
               Person<int> per = new Person<int>() // throws compiler error.

       2. cannot create instances of type parameters.
               public static <E> void append(List<E> list) {
                        E elem = new E();  // compile-time error
                        list.add(elem);
             }
     
 3. cannot declare static fields whose types are type parameters.
                public class MobileDevice<T> {
                            private static T os;  // compiler error.
                }  
 4. cannot use casts or instance of with parameterised types. Because the Java compiler erases all type parameters in generic code, you cannot verify which parameterized type for a generic type is being used at runtime:
           
                 public static <E> void rtti(List<E> list) {
                         if (list instanceof ArrayList<Integer>) {  // compile-time error
                        }
                 }

Typically, you cannot cast to a parameterized type unless it is parameterized by unbounded wildcards. For example:
                  List<Integer> li = new ArrayList<>();
                  List<Number>  ln = (List<Number>) li;  // compile-time error

5. cannot create arrays of parameterised type.
             Object[] stringLists = new List<String>[];  // compiler error, but pretend it's allowed
             stringLists[0] = new ArrayList<String>();   // OK
              stringLists[1] = new ArrayList<Integer>();  // An ArrayStoreException should be thrown,
                                                                                // but the runtime can't detect it.
6. cannot create catch or throw objects of parameterised types.
A generic class cannot extend the Throwable class directly or indirectly. For example, the following classes will not compile:
                 // Extends Throwable indirectly
                 class MathException<T> extends Exception { /* ... */ }    // compile-time error

                 // Extends Throwable directly
                class QueueFullException<T> extends Throwable { /* ... */ // compile-time error

                            A method cannot catch an instance of a type parameter:

                          public static <T extends Exception, J> void execute(List<J> jobs) {
                                try {
                                        for (J job : jobs){}
         
                                   } catch (T e) {   // compile-time error
                                      }
                       }
                        You can, however, use a type parameter in a throws clause:
                       class Parser<T extends Exception> {
                                public void parse(File file) throws T {     // OK
                                }
                        }
  7. Cannot Overload a Method Where the Formal Parameter Types of Each Overload Erase to the Same Raw Type.

 public class Example {
      public void print(Set<String> strSet) { }
      public void print(Set<Integer> intSet) { }
    }
The overloads would all share the same classfile representation and will generate a compile-time error.

New Features Of Exception Handling In Java1.7


Apart of normal exception handling some new features have been introduced in java 1.7. 

Handling more than one exception with a single catch block:-
In Java SE 7 and later, a single catch block can handle more than one type of exception. This feature can reduce code duplication and lessen the temptation to catch an overly broad exception.
In the catch clause, specify the types of exceptions that block can handle, and separate each exception type with a vertical bar (|):

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

Note: If a catch block handles more than one exception type, then the catch parameter is implicitly final. In this example, the catch parameter ex is final and therefore you cannot assign any values to it within the catch block.

The try-with-resource 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. Thetry-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
The following example reads the first line from a file. It uses an instance of BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader) br = new BufferedReader(new FileReader(path))) {
          return br.readLine();
    }
}

In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after thetry keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly. 

You may declare one or more resources in a try-with-resources statement. 

Example:-

try (
        java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
        java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
    ) {
         // code that uses the resources goes here.
        }

Suppressed Exceptions:-

An exception can be thrown from the block of code associated with the try-with-resources statement. If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed, and the exception thrown by the block is the one that is thrown by the method. You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.

Bibliography:-
http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html 

Note:- Almost all the content is taken from the above site