Just because a Dog is-an Animal, it doesn't mean that a List<Dog> is-a List<Animal>. And the following example shows why. The point of generics is to give you type safety - the compiler will only allow things it knows will work. So what about the following code?
If this code is allowed, then the result is that the List<Dog> referenced by dogs contains a Cat! We've broken the type safety. So one of the lines must be faulty. Nothing wrong with line 1. Line 3 is just adding a Cat to a List<Animal> as far as the compiler is concerned (the compiler only looks at the reference type of the variables), and that should be fine. So line 2 caused the problem. That's why the compiler won't allow it.