There is the unmodifiableList
method in the Collections
class. It returns a List<T>
but in the parameters it accepts List<? extends T>
.
So if I understand this right then this method accepts a List which has T objects or objects that inherited from T class.
But I don't understand why the <? extends T>
part in the parameter. I mean the parameter determines the return type of the method. If the method is called with List<Animal>
then the return will be List<Animal>
so it is going to be the same. Why we need this <? extends T>?
Why don't we need just List<T>
in the parameter list? I don't understand this.
If you could provide an example I would be happy about it. Thank you in advance!
So if I understand this right then this method accepts a List which has T objects or objects that inherited from T class
This is oversimplifying matters.
a List<Number>
can contain solely integers. The point of a List<Number>
is that it is constrained to contain only number instances. Not that each instance MUST be Number and specifically Number - that would be impossible, as Number
is abstract (no instances of Number itself can possibly exist, only instances of some subclass of it). The only difference between a List<Integer>
containing only integers and a List<Number>
containing only integers, is that you can add, say, a Double
instance to that List<Number>
, but you can't add it to a List<Integer>
.
Because a method that takes, as argument, a List<Something>
could invoke .add()
, the type system needs to worry about the difference. It needs to do so even if this method does not, in fact, call add
at all, and never intends to. The type system doesn't know that, and you're free to change the body of a method in some future version without that breaking backwards compatibility, thus, it matters. Even if you feel like it does not.
That then also explains your question:
If you have some method that demands a List<Number>
, then you may provide a List<Integer>
to Collections.unmodifiableList
, and that's fine - Collections.uL will give you that List<Number>
. This would ordinarily be broken, in that you can invoke .add(someDouble)
which you should not be doing to a list of integers, but .add
doesn't work on an unmodifiable, so it's fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With