Saturday, November 15, 2014

Generics

Generic Types & Methods :- 
e.g. Generic Type -- public class List
      Generic Method -- public void add(List elements)

Type-safe - A program is type safe when it compiles without  any errors & warnings & does not raise classcast exception at runtime.

Enum, Inner callse & exception can not be generic types.

Concrete parameterized types -- List<String>
Non - Concrete parameterized types -- List<? extends List>

Array of concrete parameterized type is not allowed.
Rawtype :- Generic type without type argument.

Collection of concrete parameterized type is allowed.

Generic Type


/**
 * Generic version of the Box class.
 * @param  the type of value being boxed
 */
public class Box {

    // T stands for "Type"
    private T t;

    public void add(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}

Box integerBox = new Box();
 
The most commonly used type parameter names are:
  • E - Element (used extensively by the Java Collections Framework)
  • K - Key
  • N - Number
  • T - Type
  • V - Value
  • S,U,V etc. - 2nd, 3rd, 4th types

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.
e.g.
     public static  boolean compare(Pair p1, Pair p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
     } 

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).

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

Type Inference

Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.
To illustrate this last point, in the following example, inference determines that the second argument being passed to the pick method is of type Serializable:
static  T pick(T a1, T a2) { return a2; }
Serializable s = pick("d", new ArrayList());

Wildcards

In generic code, the question mark (?), called the wildcard, represents an unknown type.?  -  unbound wildcard.
? extends Type  - a wildcard with upper bound. It stands for family of all types that are subtypes of Type.
? super Type - a wildcard with lower bound. It stands for family of all types that are supertypes of Type.

Overriding, overloading generic type method take precautions as multiple overload methods of generic sub-type results into only one method after compilation.

Wildcards broaden the set of argument or return types that a method accepts or returns. 

Wildcards and Subtyping

List al = new ArrayList<>();

List nl = al; // COMPILE TIME ERROR

Although Integer is a subtype of Number, List is not a subtype of List and, in fact, these two types are not related. The common parent of List and List is List.

List al = new ArrayList<>();

List nl = al; // NO ERROR

Guidelines for Wildcard Use

For purposes of this discussion, it is helpful to think of variables as providing one of two functions:

An "In" Variable
An "in" variable serves up data to the code. Imagine a copy method with two arguments: copy(src, dest). The src argument provides the data to be copied, so it is the "in" parameter.
An "Out" Variable
An "out" variable holds data for use elsewhere. In the copy example, copy(src, dest), the dest argument accepts data, so it is the "out" parameter.
Of course, some variables are used both for "in" and "out" purposes — this scenario is also addressed in the guidelines.
You can use the "in" and "out" principle when deciding whether to use a wildcard and what type of wildcard is appropriate. The following list provides the guidelines to follow:

Wildcard Guidelines: 
  • An "in" variable is defined with an upper bounded wildcard, using the extends keyword.
  • An "out" variable is defined with a lower bounded wildcard, using the super keyword.
  • In the case where the "in" variable can be accessed using methods defined in the Object class, use an unbounded wildcard.
  • In the case where the code needs to access the variable as both an "in" and an "out" variable, do not use a wildcard.

 

In Java SE 7 and later, 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 determine, or infer, the type arguments from the context. This pair of angle brackets, <>, is informally called the diamond. For example, you can create an instance of Box with the following statement:
 
Box integerBox = new Box<>();


Type Erasure

When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.

Restrictions on Generics

To use Java generics effectively, you must consider the following restrictions:

Reference
http://docs.oracle.com/javase/tutorial/java/generics/index.html