Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why unmodifiableList in Collections parameter is <? extends T>

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!

like image 930
dombimihaly89 Avatar asked Sep 06 '25 20:09

dombimihaly89


1 Answers

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.

like image 147
rzwitserloot Avatar answered Sep 09 '25 14:09

rzwitserloot