泛型的实例上界与下界
编译报错,主要原因是,fruit是可以添加香蕉,苹果等水果的,但是实例就只给了Apple的List,
编译前报错
我们可以通过强转来避免避免报错,添加Banana运行时也不会报错,这实际上是一个很严重的bug,我们明明是一个Apple的实例却装了香蕉 ,为什么运行时会不报错,主要是因为,泛型在编译时会类型擦除,会把泛型的东西抹成Object,这就有点狗,写业务也可能会有意向不到的bug,
解决方式就是确定他的上界
这样的后果就是,不能给list添加或者修改了,约定我一定不会做这种可能出bug的傻事,但是这种行为又会有什么场景呢,其实他们通常出现在方法中,除了这种场景,其他基本遇不到,统一对上界的类的泛型列表做获取处理
public static void main(String[] args) {
getListWeight(new ArrayList<Apple>());
getListWeight(new ArrayList<Banana>());
getListWeight(new ArrayList<Fruit>());
}
<pre><code>private static int getListWeight(ArrayList<? extends Fruit> fruits) {
int weights = 0;
for (Fruit fruit:fruits) {
weights += fruit.getWeight();
}
return weights;
}
除了为泛型添加上界,我们还可以为泛型添加下界
ArrayList<? super Apple> arrayList = new ArrayList<Fruit>();
这种情况是可以添加修改,但是不能获取类的实例,道理也很简单,我一个可以放Fruit的容器放几个苹果怎么了,但是不能取,Friut的容器里面取出来的东西可不指定是苹果,他的应用场景也很有限
ArrayList<Fruit> arrayList = new ArrayList<>();
new Apple().add(arrayList);</p>
<p>public class Apple extends Fruit{
@Override
int getWeight() {
return 1;
}</p>
<pre><code>public void add(ArrayList<? super Apple> arrayList) {
arrayList.add(this);
}
}
这样我们就可以给add的list不只是填入Apple的list的,还可以填Friut的List,这本身体也是很合理的
就不用写重载了,重载还不支持多态,太蠢了
评论区