• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

When a casting error is run time or compiler error

 
Kendall Ponder
Ranch Hand
Posts: 205
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the rule for when a casting error shows up as a run time error vs. a compiler error. For example:



Trying to cast an int as a String shows up as a compiler error but trying to cast the super class into the sub class isn't caught by the compiler and is a run time exception. Why doesnt' the compiler catch the second problem? Can it only find casting errors involving primitives? Thanks!
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can find a detailed explanation in this thread (it's about instanceof operator but as you will see casting & instanceof are related...). This thread might help as well.
 
Kendall Ponder
Ranch Hand
Posts: 205
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So the compiler can't tell the difference between


and

and

until the code runs. Which means it allows a casting from any class in a hierarchy to any other class in the hierarchy because it is possible for it to be legal. Right?
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kendall Ponder wrote:So the compiler can't tell the difference between code snippets until the code runs.

The compiler is not involved when the code is ran. That's why you have javac (the java compiler) to compile your classes and java to run your classes. The compiler makes sure you don't do things which are forbidden (like trying to cast a Cat to a Dog). If you do something forbidden, you'll get a compiler error (and no class file). So the compiler does NOT care what happens at runtime, it's only interested in what it knows at compile time.

In this code snippet:the compiler doesn't care to which object reference variable a is referring to, it's only interested in the type of the reference variable. In line2 the compiler doesn't have any knowledge about the type of the actual object reference variable a is referring to. It only knows the type of a is Animal and because Dog extends Animal, the compiler allows this cast, because a could refer to a Dog object. The same applies to line3: the compiler doesn't know anything about the type of the actual object reference variable d, it only knows that the type of d is Dog and because Dog and Cat are siblings (and thus not in the same class hierarchy), there is NO way d can refer to a Cat object and therefore you'll get a compiler error on line3. Hope that makes sense!

And this code really illustrates why the compiler doesn't care about what happens at runtime:Now the compiler simply can't know to which object reference variable a will be referring to, because it depends on a command line parameter when the program is ran. But you can only run the program if it's compiled! But the compiler will still do a bunch of checks: e.g. is the type of reference variable a compatible with the return type of method createAnimal; is the type of every return value compatible with the return type of method createAnimal;...

Kendall Ponder wrote:Which means it allows a casting from any class in a hierarchy to any other class in the hierarchy because it is possible for it to be legal. Right?

No! It all depends if both class belong to the same class hierarchy. If both classes belong to a different class hierarchy (like Cat and Dog; String and Integer; Cat and String;...) you'll get a compiler error if you try to cast. If classes belong to the same class hierarchy (like Object, Animal and Cat; Object, Throwable, Exception, RuntimeException and IllegalArgumentException;...) you won't get a compiler error but you risk a runtime ClassCastException when the type and the actual object are not compatible. More info about different class hierarchies and its consequences can be found in this thread. Note: it's about the instanceof operator, but the same rules apply to casting as well. And if interfaces are involved, it gets even a little trickier. More info in this thread.

Hope it helps!
Kind regards,
Roel
 
Kendall Ponder
Ranch Hand
Posts: 205
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the help. When I said

Which means it allows a casting from any class in a hierarchy to any other class in the hierarchy because it is possible for it to be legal. Right?


I was referring to the compiler which I believe you confirmed. To summarize in my own words: The compiler only declares a casting error if the classes are in different hierarchies. It is the programmer's job to insure against a runtime ClassCastException if the classes are in the same hierarchy. Casting and instanceof have the same rules.
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kendall Ponder wrote:To summarize in my own words: The compiler only declares a casting error if the classes are in different hierarchies. It is the programmer's job to insure against a runtime ClassCastException if the classes are in the same hierarchy. Casting and instanceof have the same rules.

Spot-on!

You could use the instanceof operator to ensure against a runtime ClassCastException being thrown. For example:

Hope it helps!
Kind regards,
Roel
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic