Java 泛型 list <?extends animal>和 list <Animal>
2016-12-04 08:49
267 查看
原文来自stakeoverflow 链接:http://stackoverflow.com/questions/2575363/generics-list-extends-animal-is-same-as-listanimal
The difference between
With
you know what you have is definitely a list of animals. It's not necessary for all of them to actually be exactly 'Animal's - they could also be derived types. For example, if you have a List of Animals, it makes sense that a couple could be Goats, and some
of them Cats, etc - right?
For example this is totally valid:
Just a sidenote - the following would not be valid:
Of course if we're absolutely certain aL.peek() is a cat, we can do this:
With
For example:
This is actually not a declaration of the type of object L can hold. It's a statement about what
kinds of lists L can reference.
For example, at this point,
would be something we could do.
But even after that assignment, all the compiler knows about L is that it is a List of [either Animal or a subtype of Animal]s
So now the following is not valid:
Because for all we know, L could be referencing a list of Goats - to which we absolutely cannot add an Animal.
Why not? Well, let's see:
The reason the above doesn't work is we are attempting to cast an Animal as a Goat. That doesn't work, because what if after doing that we tried to make that Animal do a 'headbutt', like a goat would? We don't necessariliy know that the Animal can do that.
It is not.
that the value which is assigned to this variable must be of "type"
This however doesn't mean that there must only be
there can be subclasses too.
You use the
but the List object itself doesn't need to be of type
can any other list of subclasses (like
This is sometime use for method arguments to say "I want a list of
but I don't care if it is just
it can be a
This avoid some weird down casts if you have a list of some subclasses, but the method expects a list of the baseclass.
This is not working as you expecting
not a
But if you wrote
even as they aren't
Note: This whole stuff is unrelated to inheritance of the objects in the list itself. You still can add
in a
with or without
The difference between
List<Animal>and
List<? extends Animal>is this:
With
List<Animal>,
you know what you have is definitely a list of animals. It's not necessary for all of them to actually be exactly 'Animal's - they could also be derived types. For example, if you have a List of Animals, it makes sense that a couple could be Goats, and some
of them Cats, etc - right?
For example this is totally valid:
List<Animal> aL= new List<Animal>(); aL.add(new Goat()); aL.add(new Cat()); Animal a = aL.peek(); a.walk();//assuming walk is a method within Animal
Just a sidenote - the following would not be valid:
aL.peek().meow();//we can't do this, as it's not guar 4000 anteed that aL.peek() will be a Cat
Of course if we're absolutely certain aL.peek() is a cat, we can do this:
((Cat)aL.peek()).meow();//will generate a runtime error if aL.peek() is not a Cat
With
List<? extends Animal>, you're making a statement about the type of list you're dealing with.
For example:
List<? extends Animal> L;
This is actually not a declaration of the type of object L can hold. It's a statement about what
kinds of lists L can reference.
For example, at this point,
L = aL;//remember aL is a List of Animals
would be something we could do.
But even after that assignment, all the compiler knows about L is that it is a List of [either Animal or a subtype of Animal]s
So now the following is not valid:
L.add(new Animal());//throws a compiletime error
Because for all we know, L could be referencing a list of Goats - to which we absolutely cannot add an Animal.
Why not? Well, let's see:
List<Goat> gL = new List<Goat>();//fine gL.add(new Goat());//fine gL.add(new Animal());//compiletime error
The reason the above doesn't work is we are attempting to cast an Animal as a Goat. That doesn't work, because what if after doing that we tried to make that Animal do a 'headbutt', like a goat would? We don't necessariliy know that the Animal can do that.
It is not.
List<Animal>says
that the value which is assigned to this variable must be of "type"
List<Animal>.
This however doesn't mean that there must only be
Animalobjects,
there can be subclasses too.
List<Number> l = new ArrayList<Number>(); l.add(4); // autoboxing to Integer l.add(6.7); // autoboxing to Double
You use the
List<? extends Number>construct if you are interest in an list which got
Numberobjects,
but the List object itself doesn't need to be of type
List<Number>but
can any other list of subclasses (like
List<Integer>).
This is sometime use for method arguments to say "I want a list of
Numbers,
but I don't care if it is just
List<Number>,
it can be a
List<Double>too".
This avoid some weird down casts if you have a list of some subclasses, but the method expects a list of the baseclass.
publid void doSomethingWith(List<Number> l) { ... } List<Double> d = new ArrayList<Double>(); doSomethingWith(d); // not working
This is not working as you expecting
List<Number>,
not a
List<Double>.
But if you wrote
List<? extends Number>you can pass
List<Double>objects
even as they aren't
List<Number>objects.
publid void doSomethingWith(List<? extends Number> l) { ... } List<Double> d = new ArrayList<Double>(); doSomethingWith(d); // works
Note: This whole stuff is unrelated to inheritance of the objects in the list itself. You still can add
Doubleand
Integerobjects
in a
List<Number>list,
with or without
? extendsstuff.
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Debian 7.x 安装Oracle JAVA
- springmvc实现url路由功能
- spring boot 配置 druid/** * 配置druid * Created by adam on 4/11/16. */ @Configuration public class D
- api接口rsa加密
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解