The issue of variance (particularly contravariance) has got me banging my head against the wall for a week. I have finally understood the theory, thanks to a couple of questions on here, and now as soon as I start working on it, I am getting errors I just don't understand.
I have a simple heirarchy of classes:
abstract class Fruit, Mango extends Fruit, Orange extends Fruit, BloodOrange extends Orange
abstract class Fruit implements PlantEatable {
    private boolean isRipe;
    private boolean isEatable;
    public boolean isRipe() {
        return isRipe;
    }
    public void setRipe(boolean ripe) {
        isRipe = ripe;
    }
    @Override
    public boolean isEatable() {
        return isEatable;
    }
    public void setEatable(boolean eatable) {
        isEatable = eatable;
    }
}
public class Mango extends Fruit {
}
public class Orange extends Fruit{
}
public class BloodOrange extends Orange{
}
Now, The Oracle documentation generally has been great about Generics except for the part that was the most important I find confusing: https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html
If I am doing PECS which is Producer Extends Consumer Super
I am trying to do something very simple:
public class UpperBoundEg {
    public static <E> void copy(List<? extends E> src, List<? super E> dest) {
        src.forEach( item -> {
            dest.add(item);
            System.out.println("Added to dest: " + item.getClass());
        });
    }
    public static <E> void acceptTest(List<? super Orange> objects) {
    }
    public static void main(String[] args) {
        //Producer
        List<? extends Orange> oranges = new ArrayList<>();
        //oranges.add(new Orange()); // Doesn't work because its a producer ?
        //Consumer
        List<? super BloodOrange> objects = new ArrayList<>();
        objects.add(new BloodOrange());
        //objects.add(new Orange()); // Why doesn't it work ?
        //objects.add(new Object()); // Why doesn't it work ?
        copy(
                Arrays.asList(
                        new Orange(),
                        new Orange(),
                        new BloodOrange(),
                        new Object(), 
                        new Mango() // Why is this allowed?
                ),
                new ArrayList<>()
        );
    }
}
Why is this happenning ? I thought List<? super BloodOrange> should take BloodOrange and all its super classes ? Why is it only accepting BloodOrange ?
And Why am I able to add a Mango to the copy function ?

