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
?

- 8,532
- 3
- 51
- 77

- 71
- 6
-
4Can the compiler *always know* that the base class reference is actually to a derived class? Can it *always know* to which derived class? – StoryTeller - Unslander Monica Aug 28 '21 at 21:23
-
4"to be sure that the programmer knows what they are doing" applies just as much to casting to a subclass. If I have a reference whose type is a superclass, the compiler has no way of knowing what subclass the reference actually is. If it lets you use a superclass instance as a subclass without explicit casting, you lose compile time protection. The safe way to cast to a subclass is to use `instanceof` – tgdavies Aug 28 '21 at 21:24
-
If you might get a class cast exception, it's helpful for the code to indicate where casting occurs. – khelwood Aug 28 '21 at 21:25
-
So ,unlike typecasting for primitives types, it's not about memory allocation it's about referincing beacuse the compiler know that a sub class has only one super class but a super class can have many sub classes and that's why we must precise which one of them to convert to it . im right or im not ? and thanks for your answers even the -1 rate – Ramzi Bouali Aug 28 '21 at 21:43
-
4Sort of, but don't think of it as a 'conversion'. A cast does nothing except check that the type you are casting to is the runtime type of the instance. – tgdavies Aug 28 '21 at 21:47
1 Answers
TL;DR:
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.

- 9,715
- 8
- 45
- 66