I guess the jvm never allows downcasts
compiler that it wants 'a' to be a Dog reference rather than an Animal reference, and is that all right. ...and then after
the compiler allows both the cast and the assignment
After down cast compiler see reference variable a as a dog type referencence not animal type reference. My meaning is we do manual explicit cast in such a way that we say a is really refering to dog object.
that is why upcast happens automatically and down cast happens manually.
Animal a2 = (Dog)a; // Dog is in the same inheritance tree as a's reference type Animal, so the compiler allows the cast;
//the compiler has allowed the cast now it checks the assignment--and it will NOT allow you to assign a Dog reference
//to an Animal reference (it still knows nothing of the actual object type in a) so it reports an "incompatible type" error