Hi,
The declaration of asList is : public static <T> List<T> asList(T... a)
So when you write : List<Snow> snow2 = Arrays.asList(a); the compiler expects that a is an array of Snow. OK
When you give a to asList, the compiler has to find the type of a.
With asList(new Light(), new Heavy()); the compiler finds that the "common denominator" for the type is Powder and not Snow ! So it complains.
With asList(new Powder(), new Crusty()); the common denominator is ... Snow, so the compiler is happy.
For addAll the declaration is : boolean addAll(Collection<? extends E> c)
So, in a List of Snow, you can add any object whose the type extends Snow.
Tht's why
List<Snow> snow3 = new ArrayList<Snow>();
Collections.addAll(snow3, new Light(), new Heavy());
works fine.
I hope it's quite clear and above all that I didn't any mistake.