I am trying to understand bounded types and not quite grasping the point of them.
There is an example of bounded generics on which provides this use case:
public class NaturalNumber<T extends Integer> {
private T n;
public NaturalNumber(T n) { this.n = n; }
public boolean isEven() {
return n.intValue() % 2 == 0;
}
// ...
}
If you are going to restrict the classes that can be the parameterized type, why not just forget the parameterization all together and have:
public class NaturalNumber {
private Integer n;
public NaturalNumber(Integer n) { this.n = n; }
public boolean isEven() {
return n.intValue() % 2 == 0;
}
// ...
}
Then any class that extends/implements Integer
can be used with this class.
Also, a side question: How is T
extending Integer
in the first example when the Java Integer
class is final?
T
can only beInteger
, so the "extends" here is purely symbolic. (I'm starting with the side-note because, indeed, it's an example where generics are useless. I truly have no idea why the tutorial thinks this is an informative demonstration. It's not.)Suppose instead that
T extends Number
:So the point of generics in general, is that you can do this:
Generics are a form of parametric polymorphism, essentially it lets us reuse code with a generality regarding the types involved.
So what's the point of a bound?
A bound here means that
T
must beNumber
or a subclass ofNumber
, so we can call the methods ofNumber
on an instance ofT
.Number
is unfortunately a generally useless base class on its own (because of precision concerns), but it might let us do something interesting like:It's more common, for example, to find
T extends Comparable<T>
which lets us do something more meaningful withT
. We might have something like:And now our
Example
class has a natural ordering. We can sort it, even though we have no idea whatT
actually is inside the class body.If we combine these concepts, that:
we could build constructs such as: