Quick Reference :
- Bounded means the class is bounded a type it cannot be other than than
- class Test<T extends Number> {}
- Example : Arithmetic Operation is performed in a Generic class so we can say that the class in bounded to Numbers hence T extends Number
- Numbers class can hold : Byte, Short, Integer, Long, Float and Double
- We can bound a parameter by using keyword extends
- Even for interface we use extends keyword only. (Implements keyword cannot be used)
- Only the methods available on the extended class can be used inside the generic class
- If anything except the child class of the bounded class is passed to the generic class then compile time error occurs with message “Type parameter String is not within its bound” since we are expecting Integer here.
- If you want the type parameter to be of Two Types example a Number class which extends Integer, we can do that by using & character
- Example : class Test <T extends Number & Runnable>
- In above class Type Parameter T Object should be a child class of Number which extends Runnable
- Order of Bounded type (Example in details below)
- First class & interface1 & Interface2
- Interface & class (Not Allowed)
- class & class (Not Allowed)
- Conclusions :
- There are many cases in which the developer does not want certain input type as a parameter, hence developer can restrict the types by using Bounded Type Parameter.
- When you declare the Type in class or a method declaration using <T> diamond operator you can extend an Interface here <T extends Number> so tell the Type that you are expecting only those type(classes) which implements the Number interface.
Example1 : Bounded Type Method
public class BoundedTypeDemo1 { public static <T extends Comparable<T>> T findMin(T t1, T t2) { if(t1.compareTo(t2) > 0) { return t2; }else { return t1; } } public static void main(String[] args) { System.out.println(findMin(10,20)); System.out.println(findMin("Hello","World")); System.out.println(findMin(44.3,22.4)); } }
Example2 : Bounded Type Class
package com.test; public class BoundedTypeDemo2 { public static void main(String[] args) { new CalcNumber<Integer>(10,20).printSum(); new CalcNumber<Double>(10d,20d).printSum(); } } class CalcNumber<T extends Number> { T input1; T input2; CalcNumber(T input1, T input2) { this.input1 = input1; this.input2 = input2; } public void printSum() { if (input1.getClass().equals(Double.class)) { System.out.println(input1.doubleValue() + input2.doubleValue()); }else if (input1.getClass().equals(Integer.class)) { System.out.println(input1.intValue() + input2.intValue()); } } }
Note : A Type can extend a class as well as an Interface, in Example1 Type extends an interface but in Example2 Type extends a class
Multiple Bounds
A Type parameter can have multiple Bounds
Syntax :
public static <T extends Class & Interface<T>> return_type method_name(T x, T y, T z)
Example :
public static <T extends Number & Comparable<T>> T maximum(T x, T y, T z)
maximum – Is the name of the generic method
T – is a generic parameter
- The T type should be a class that extends class Number and implement Comparable interface
- In case a class is passed as bound, it should be passed first before interface otherwise compile time error will occur.
Order of Multiple Bounds :
- class Test <T extends Runnable & Comparable>
- Valid
- class Test <T extends Number & Runnable & Comparable>
- Valid
- class Test <T extends Runnable & Comparable & Number>
- Invalid since class should be first followed by Interface
- class Test <T extends Number & Runnable>
- Invalid since two classes cannot be extended to a Type
Reference :