• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

The ClassCastException and the compiler error "incompactible types..."

 
Kamil Hlubek
Ranch Hand
Posts: 49
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys,

I have a question, because of the ClassCastException and the compiler errors, which occur if you cast a reference's variable type in a type of a complete different hierarchy than the reference's variable type actually is.

Here is the code I do not understand completely:



My question now is, why the code compiles ( I am awared of that the code throws a ClassCastException at runtime ) generally?
I am asking this question, because if a class should be cast into another class ( or here the interface Printable ), then the class to be casted have to pass the IS-A test with the type to cast and if the reference variable's type and the type to cast to are in different hierachies, then the compiler does not allow it and a compiler error occurs, which sounds like "incompactible types: X cannot be converted to Y".

To be more precisely: The class BlackInk inherits from Ink, but nobody of them implements the Printable interface, so it should not compile in my opinion, because the reference's variable type and the type to cast to are in different hierarchys, but it compiles, what should have to do with that, that the compiler can not check the implemented interfaces or something like that.
I have tried to make of the interface a class and it did not work, so you guys would only have to think about it, where I stopped if you want to help me, wherefore I would thank you very much.
 
Roel De Nijs
Sheriff
Posts: 10666
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kamil Hlubek wrote:To be more precisely: The class BlackInk inherits from Ink, but nobody of them implements the Printable interface, so it should not compile in my opinion, because the reference's variable type and the type to cast to are in different hierarchys

The only reason why the above code compiles, is because the BlackInk class is not final. That means somebody can create a subclass which implements the Printable interface, like And then it's perfectly valid to change line8 toAnd then the TwistInTaleCasting class will compile successfully and execute without any runtime exceptions.

And as you probably already have understood from this explanation, if you would change the BlackInk class declaration toyou'll get the "incompatible types" compiler error.

For more detailed information have a look at this thread (about exactly the same code snippet), this thread (also similar code snippet and an additional one) and this thread (about casting or using instanceof operator on a class vs an interface).

Hope it helps!
Kind regards,
Roel
 
Kamil Hlubek
Ranch Hand
Posts: 49
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote:
Kamil Hlubek wrote:To be more precisely: The class BlackInk inherits from Ink, but nobody of them implements the Printable interface, so it should not compile in my opinion, because the reference's variable type and the type to cast to are in different hierarchys

The only reason why the above code compiles, is because the BlackInk class is not final. That means somebody can create a subclass which implements the Printable interface, like And then it's perfectly valid to change line8 toAnd then the TwistInTaleCasting class will compile successfully and execute without any runtime exceptions.

And as you probably already have understood from this explanation, if you would change the BlackInk class declaration toyou'll get the "incompatible types" compiler error.

For more detailed information have a look at this thread (about exactly the same code snippet), this thread (also similar code snippet and an additional one) and this thread (about casting or using instanceof operator on a class vs an interface).

Hope it helps!
Kind regards,
Roel



Thank you for the good ( and fast ) response !

I am going to read all the threads you have posted and understand everything about the ClassCastException.
 
Guillermo Ishi
Ranch Hand
Posts: 789
C++ Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I remember reading if your reference is an interface type the compiler will accept any cast there. Except for final classes.
 
Henry Wong
author
Marshal
Pie
Posts: 22124
88
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Guillermo Ishi wrote:I remember reading if your reference is an interface type the compiler will accept any cast there. Except for final classes.


... which Roel explained in detail a few posts above.

Henry
 
Roel De Nijs
Sheriff
Posts: 10666
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
Guillermo Ishi wrote:I remember reading if your reference is an interface type the compiler will accept any cast there. Except for final classes.

You are spot-on!

If you have nothing but interfaces, you can cast and/or use instanceof operator without ever getting a compiler error. Remember with casting you can get a ClassCastException at runtime (using the instanceof operator you'll never get a ClassCastException at runtime, it returns either true or false). Some code examples to illustrate

When you have classes and interfaces, it all depends if the class is marked final or not. For a non-final class the same rules as for interfaces apply. But if ClassX is a final class, you'll get a compiler error if ClassX IS-NOT-A InterfaceY, both with a cast and/or the instanceof operator. Another batch of code examples to illustrate

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