How can we restrict Generics (type parameter) to sub classes of a particular class 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.

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>

Example

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();
   }
}

Compile time error

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

Multiple bounds

You can also list multiple types as bounded parameters using the extends keyword separating them using “&” thee, The (type) parameter passed to this class should be subtype of all the specified classes.

Example

In the following example we are setting the Number and Comparable types of upper bounds i.e. this class accepts types which are sub classes of both classes.

class Sample <T extends Number & Comparable<T> >{
   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>(22);
      obj1.display();
      Sample<Double> obj2 = new Sample<Double>(20.22d);
      obj2.display();
   }
}

Output

Data value is: 22
Data value is: 20.22

If you pass an AtomicInteger class as a parameter to the Sample class, since it is not a sub type of the comparable class, a compile time error will be generated

Example

import java.util.concurrent.atomic.AtomicInteger;
class Sample <T extends Number & Comparable<T> >{
   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>(22);
      obj1.display();
      Sample<Double> obj2 = new Sample<Double>(20.22d);
      obj2.display();
      Sample<AtomicInteger> obj3 = new Sample<AtomicInteger>(124);
      obj3.display();
   }
}

Compile time error

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
Updated on: 2026-03-11T22:50:45+05:30

3K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements