Bounded-types in generics in Java?

Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class. These are known as bounded-types in generics in Java.
You can declare a bound parameter just by extending the required class with the type-parameter, within the angular braces as −
class Sample <T extends Number>
In the following Java example the generic class Sample restricts the type parameter to the sub classes of the Number classes using the bounded parameter.
 Live Demo
class Sample <T extends Number>{
   T data;
   Sample(T data){
      this.data = data;
   }
   public void display() {
      System.out.println("Data value is: "+this.data);
   }
}
public class BoundsExample {
   public static void main(String args[]) {
      Sample<Integer> obj1 = new Sample<Integer>(20);
      obj1.display();
      Sample<Double> obj2 = new Sample<Double>(20.22d);
      obj2.display();
      Sample<Float> obj3 = new Sample<Float>(125.332f);
      obj3.display();
   }
}
Data value is: 20
Data value is: 20.22
Data value is: 125.332
Now, if you pass other types as parameters to this class (say, String for example) a compile time error will be generated.
 Live Demo
public class BoundsExample {
   public static void main(String args[]) {
      Sample<Integer> obj1 = new Sample<Integer>(20);
      obj1.display();
      Sample<Double> obj2 = new Sample<Double>(20.22d);
      obj2.display();
      Sample<String> obj3 = new Sample<String>("Krishna");
      obj3.display();
   }
}
BoundsExample.java:16: error: type argument String is not within bounds of type-variable T
      Sample<String> obj3 = new Sample<String>("Krishna");
            ^
   where T is a type-variable:
      T extends Number declared in class Sample
BoundsExample.java:16: error: type argument String is not within bounds of type-variable T
      Sample<String> obj3 = new Sample<String>("Krishna");                                 ^
   where T is a type-variable:
      T extends Number declared in class Sample
2 errors
Just like with classes to define bounded-type parameters for generic methods, specify them after the extend keyword. If you pass a type which is not sub class of the specified bounded-type an error will be generated.
In the following example we are setting the Collection<Integer> type as upper bound to the typed-parameter i.e. this method accepts all the collection objects (of Integer type).
 Live Demo
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
public class GenericMethod {
   public static <T extends Collection<Integer>> void sampleMethod(T ele){
      Iterator<Integer> it = ele.iterator();
      while (it.hasNext()) {
         System.out.println(it.next());
      }
   }
   public static void main(String args[]) {
      ArrayList<Integer> list = new ArrayList<Integer>();
      list.add(24);
      list.add(56);
      list.add(89);
      list.add(75);
      list.add(36);
      sampleMethod(list);
   }
}
24
56
89
75
36
Now, if you pass types other than collection as typed-parameter to this method, it generates a compile time error.
 Live Demo
public class GenericMethod {
   public static <T extends Collection<Integer>> void sampleMethod(T ele){
      Iterator<Integer> it = ele.iterator();
         while (it.hasNext()) {
            System.out.println(it.next());
         }
      }
   public static void main(String args[]) {
      ArrayList<Integer> list = new ArrayList<Integer>();
      list.add(24);
      list.add(56);
      list.add(89);
      list.add(75);
      list.add(36);
      sampleMethod(list);
      Integer [] intArray = {24, 56, 89, 75, 36};
      sampleMethod(intArray);
   }
}
GenericMethod.java:23: error: method sampleMethod in class GenericMethod cannot be applied to given types;
      sampleMethod(intArray);
      ^
   required: T
   found: Integer[]
   reason: inferred type does not conform to upper bound(s)
      inferred: Integer[]
      upper bound(s): Collection<Integer>
   where T is a type-variable:
      T extends Collection<Integer> declared in method <T>sampleMethod(T)
1 error