Java's typecasting
of primitives
should be explicate when we move from a wide-type to a narrow-type because it poses the risk of data-loss. The compiler wants to be sure that the person writing the code is not injecting any errors into her code. I don't understand why typecasting
a super class
, into a sub-class
, is explicit? Maybe it is due to memory being used for the members of the super class
?
Because compiler knows, that Dog IS-A Animal, but Animal is not a Dog (it may be, though).
class Animal { ... }
class Dog Extends Animal { ... }
class Program {
public static void main(String[] args) {
Animal a = new Dog(); //✓ compiler knows, that Dog IS-A Animal;
Dog d = new Animal(); //x compiler does NOT know, that Animal IS-A Dog
}
}
To dive in a bit deeper into your question, actually, it boils down to how the compiler (javac
, in this case) is designed.
Sure, compiler could have been designed in a less-defensive way - allowing all the casts to be validated at runtime, letting everything happen, and throwing exceptions like a firework.. and you can guess, that's bad from the perspective of engineer, type-safety, security, or just coding.
The way type narrowing (down-casting) and/or widening (up-casting) work, in Java, is, in principle (not technically, though), same, for both - primitives and objects.
With respect to primitives, the only reason why explicit casting is still needed during narrowing-conversion between compatible types, is because of compiler "wants to make sure", you didn't inadvertently assigned the value of a bigger type, to the variable of smaller type, as this may cause problems. Therefore, you have to explicitly mention that.. announce.. declare out loudly, that YES! you want this narrowing to happen, because you are sure nothing will go wrong, and in that case, compiler "trusts your promise" and compilation is successful. If something will still go wrong, at runtime, that's already not something you did by overlooking types.
On the other hand, the other way around (assigning narrower type to the wider one) is always safe, hence - no explicit casting is needed.
The reason with reference types is identical - Dog
can always be referred as Animal
(assuming Dog extends Animal
), but not every Animal
is guaranteed to be a Dog
. So, you have to be explicit here, as well, because there is a similar chance of committing something wrong.. and by explicit downcast, you "promise to the compiler", that you have examined the code, at least, twice.
So, that's the way javac
compiler is designed. This is an extra layer of safety, Java provides.