You need an "instanceof" test before the downcast to ensure, otherwise, it will throws an exception.
//d1 = (Dog)new Animal(); ##1 this gives a runtime error as Animal is not an instance of Dog
It give a runtime error simply you were creating an anonymous object instead of Animal with statement "new Animal();" on the cast. Change it to "d1 = (Dog)a;" like you did and it will fix the problem.
Here is a recap and hope it help:
OCPJP6-05-11
"Your life is in your hands, to make of it what you choose."