IDENTIFYING ERRORS IN CODE
10/8/21, 9:26 PM inheritance - java.lang.ClassException: A cannot be cast into B - Stack Overflow
https://stackoverflow.com/questions/17217965/java-lang-classexception-a-cannot-be-cast-into-b 1/8
java.lang.ClassException: A cannot be cast into B Asked 8 years, 3 months ago Active 1 year, 11 months ago 20k timesViewed
15
4
I implemented this code:
{ }
{ }
{ { (B) (); (B) (); } }
class A //some code
class B extends A // some code
class C public static void main(String []args)
B b1 = new A A a1 = new A
Both of these lines, when compiled separately, compile fine,but give runtime error with .java.lang.ClassException: A cannot be cast into B
Why they compile well, but give a runtime error?
java inheritance
Share Improve this question Follow edited Jun 20 '13 at 15:47 blackpanther 10k 10 43 76
asked Jun 20 '13 at 15:40 Ozil 925 3 11 28
Because an instance of has nothing to do with . And that's a runtime check.A B – Brian Roach Jun 20 '13 at 15:43
4
Seriously, this is basic OOP. But looks like people don't care about it and prefer to post answers and upvote when this is widely explained in the net. – Luiggi Mendoza Jun 20 '13 at 15:54
7
Consider the classic example: . By the cast, you're telling the compiler to trust you that you're not going to do mistakes. But, in runtime, your program will crash since you're not really know what you're doing.
Is dog an animal? . Is animal a Dog? . But not alwaysYes Maybe
– Maroun Jun 20 '13 at 15:55
13 Answers Active Oldest
Variables of type can store references to objects of type or its subtypes like in your case class .
A A
B
Votes
10/8/21, 9:26 PM inheritance - java.lang.ClassException: A cannot be cast into B - Stack Overflow
https://stackoverflow.com/questions/17217965/java-lang-classexception-a-cannot-be-cast-into-b 2/8
10 So it is possible to have code like:
(); A a = new B
Variable is of type so it have only access to API of that class, it can't access methods added in class B which object it refers to. But sometimes we want to be able to access those methods so it should be possible to somehow store reference from in some variable of more accurate type (here ) via which we would be able to access those additional methods from class B. BUT HOW CAN WE DO THAT?
a A
a
B
Lets try to achieve it this way:
a; B b = //WRONG!!! "Type mismatch" error
Such code gives compile time error. It happens to save us from situation like this:Type mismatch
class B1 extends A
class B2 extends A
and we have .A a = new B1();
Now lets try to assign . Remember that so it needs to generate code which will be safe for all possible values.
If compiler wouldn't complain about it should also allow to compile . So just to be safe it doesn't let us do it.
B1 b = a; compiler doesn't know what actually is held under variable a
B1 b = a; B2 b = a;
So what should we do to assign reference from to ? We need to tell compiler that we are aware of potential type mismatch issue here, but we are sure that reference held in can be safely assigned in variable of type . We do so by value from to type
via .
a B1 explicitly
a B casting a B (B)a
(B)a; B b =
But lets go back to example from your question
(B) (); (B) (); B b1 = new A A a1 = new A
operator returns reference of the same type as created object, so returns reference of the type so new new A()
A
(B) (); B b1 = new A
can be seen as
10/8/21, 9:26 PM inheritance - java.lang.ClassException: A cannot be cast into B - Stack Overflow
https://stackoverflow.com/questions/17217965/java-lang-classexception-a-cannot-be-cast-into-b 3/8
(); (B) tmp; A tmp = new A B b1 =
Problem here is that .
Why such limitation exist? Lets say that derived class adds some new methods that supertype doesn't have like
you can't store reference to object of superclass in variable of its derived type
{ }
{ i; { .i=i; } }
class A // some code
class B extends A private int public void setI( i)int
this
If this would be allowed
(B) (); B b = new A
you could later end up with invoking . But will it be correct? No because instance of class A doesn't have method nor which that method uses.
b.setI(42);
setI field i
So to prevent such situation at throws .(B)new A(); runtime java.lang.ClassCastException
Share Improve this answer Follow edited Oct 17 '19 at 18:54 answered Jun 20 '13 at 16:18 Pshemo 115k 22 170 244
Awesome answer! Thanks a lot. – Ozil Jun 20 '13 at 16:38
7
The reason it fails at runtime is that the object isn't a B. It's an A. So while As can be casts as Bs, yours cannot.
some
The compilier just can't analyze everything that happened to your A object. For example.
(); ();
(B) a1; (B) a2;
A a1 = new B A a2 = new A
B b1 = // Ok B b2 = // Fails
10/8/21, 9:26 PM inheritance - java.lang.ClassException: A cannot be cast into B - Stack Overflow
https://stackoverflow.com/questions/17217965/java-lang-classexception-a-cannot-be-cast-into-b 4/8
So the compilier isn't sure whether your A object is actually castable to a B. So in the above, it would think that the last 2 lines were ok. But when you actually run the program, it realizes that
is not a B, it's only an A.a2
Share Improve this answer Follow edited Jun 20 '13 at 15:56 answered Jun 20 '13 at 15:45 Snowy Coder Girl 5,160 10 38 67
2
(B) (); A a1 = new A
Because is NOT .A B
Compile time works because you are casting and explicitly guaranteeing compiler that you are sure at runtime will be .A B
Share Improve this answer Follow answered Jun 20 '13 at 15:41 kosa 64.2k 12 119 160
2
When B extends A, it means all methods and properties of A are also present in B.
So you can ever cast B to A,
but you CANNOT cast A to B.
You have to be really care about casting in your application.
Share Improve this answer Follow answered Jun 20 '13 at 15:44 Martin Strejc 3,956 2 19 35
2
when you say B extends A, A becomes father of B now technically B has all charecteristics of A while A has charecteristics of itself onlyplus its own
if you say convert A into B and assign to B, that is ok but if you say cast A into B and assign to A, thats not possible as A here does not know extra charecteristics present in B.
and these things happens at runtime so it will give you a runtime error.
Share Improve this answer Follow answered Jun 20 '13 at 15:48 dev2d 4,031 2 26 51
10/8/21, 9:26 PM inheritance - java.lang.ClassException: A cannot be cast into B - Stack Overflow
https://stackoverflow.com/questions/17217965/java-lang-classexception-a-cannot-be-cast-into-b 5/8
2
The name it self implies the will just looks at compile-time type of the .compiler expression
It does not do assumptions on the runtime type of the .expression
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.5.1
Coming to real problem
You cast A to B.You cast B to A.When you have a Mango,You have Fruit.But when you have a Fruit,It not mean that You have a Mango.
cannot can
Share Improve this answer Follow edited Jun 20 '13 at 15:52 answered Jun 20 '13 at 15:43 Suresh Atta 116k 37 181 287
1
I'm not sure about the compile part, but I can explain the runtime error.
B extends A, which means that every object of class B, is also an object of type A. The other way around is not true.
Compare A with 'Mammal', and B with 'Cow'. A Cow is always a Mammal, but not every Mammal is a Cow.
Share Improve this answer Follow answered Jun 20 '13 at 15:43 Johanneke 4,461 3 16 32
1
Has to do with when casting is done. You are telling the compiler: "Hey, don't worry about it, this is what I say it is, if you have a problem, take it up with me at runtime."
Basically, the compiler is letting you do your thing. When you explicitly cast something, the compiler doesn't do checks. When you run, and the program tries to cast but fails, that's when you will see the error.
Share Improve this answer Follow answered Jun 20 '13 at 15:43 Captain Skyhawk 3,445 2 21 37
1
Because, all the compiler sees is that an A is cast into a B. Since some A's can actually be B's this may work for those A's. By writing the explicit cast, you ensure that this particular A is actually a valid B. However, this is not the case.
(); (); A justA = new A A anAThatIsAlsoAValidB = new B // implicit cast to supertype
10/8/21, 9:26 PM inheritance - java.lang.ClassException: A cannot be cast into B - Stack Overflow
https://stackoverflow.com/questions/17217965/java-lang-classexception-a-cannot-be-cast-into-b 6/8
(A) anAThatIsAlsoAValidB ;
(A) justA;
B b1 = // Cast an A into a B. At runtime, this will work fine! Compiler allows casting A into B. B b2 = // Cast an A into a B. At runtime, this won't work. Compiler has/uses no more info than above.
Here's why the compiler does not really know about the type:
com.example. .example.ThridPartyType(); (B) obj.getSomeA();
ThridPartyType obj = new com B b = // getSomeA() returns A and that is all the compiler knows. // Depeding on the implementation of "ThridPartyType::getSomeA()" the A returned may or may not actually also be a valid B. // Hence, if the cast works or not will only be known at runtime. If it doesn't, the Exception is thrown.
Share Improve this answer Follow edited Jun 20 '13 at 16:04 answered Jun 20 '13 at 15:50 b.buchhold 3,807 2 19 33
1
Following is a compiletime casting -
(); A a = new B
Such static castings are implicitly performed by the compiler, because the compiler is aware of the fact that B is-a A.
Following doesn't compile -
(); B b = new A
No compiletime casting here because the compiler knows that A is not B.
Following compiles -
(B) (); B b = new A
It is a dynamic casting. With you are telling the compiler explicitly that you want the casting to happen at runtime. And you get a CCE at runtime, when the runtime tries to perform the cast but finds out that it cannot be done and throws a CCE.
(B)
When you do (or have to do) something like this, the responsibility falls upon you (not the compiler) to make sure that a CCE doesn't occur at runtime.
Share Improve this answer Follow edited Feb 23 '14 at 2:13 answered Jun 20 '13 at 15:53 Bhesh Gurung
10/8/21, 9:26 PM inheritance - java.lang.ClassException: A cannot be cast into B - Stack Overflow
https://stackoverflow.com/questions/17217965/java-lang-classexception-a-cannot-be-cast-into-b 7/8
49k 20 87 139
0
It's simple. Think that when you are extending you have to use is a
B `is a` A A `is not` B
A more realistic example
{ }
{ }
{ }
class Animal
class Dog extends Animal
class Cat extends Animal
A DOG Animal AN ANIMAL a DOG necessary (Example : a cat is not a dog, and a cat is an animal)
IS A IS NOT
You are getting cause , in runtime realize that that animal is not a dog, this is call and is not safe what are you trying to do.
runtime exception
downcasting
Share Improve this answer Follow answered Jun 20 '13 at 15:42 nachokk 14.1k 4 22 49
0
The fact that means that , i.e. B is like A but probably add some other stuff.B extends A B is A
The opposite is wrong. . Therefore you cannot cast to .A is not B A B
Think this way. is . is . Is animal? Yes it is. Is any animal Bee? Not it is not. For example Dog is animal but definitely not a Bee.
A Animal B Bee Bee
Share Improve this answer Follow answered Jun 20 '13 at 15:44 AlexR 110k 14 120 197
0
Because the is a parent of . the functionality of the but keeps the original functionality of . So can in fact be cast to , but not vice versa.
A B B extends A A B A
What if added a new method, let's say . If you would try to call that method through variable on the instance (imagine that the cast worked) what would you expect? Well, you would definitely get an error because that method does not exist in .
B newMethodInB()
B A
A
10/8/21, 9:26 PM inheritance - java.lang.ClassException: A cannot be cast into B - Stack Overflow
https://stackoverflow.com/questions/17217965/java-lang-classexception-a-cannot-be-cast-into-b 8/8
Share Improve this answer Follow answered Jun 20 '13 at 15:48 darijan 9,509 23 37