泛型的实例上界与下界

编译报错,主要原因是,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&lt;? extends Fruit&gt; 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&lt;? super Apple&gt; arrayList) {
    arrayList.add(this);
}

}

这样我们就可以给add的list不只是填入Apple的list的,还可以填Friut的List,这本身体也是很合理的

就不用写重载了,重载还不支持多态,太蠢了