How to identify the cause of ClassCastException?

G

Gordon Beaton

Now, I have a State reference state, whose corresponding object was
created and filled. I believe/guess/thought it is a WarmState
object. Now I need to pass state to a method which only take
WarmState parameter. So I cast state to WarmState type. But I ran
into ClassCastException.

Obviously your state object wasn't a WarmState. So catch the exception
and display e.g. state.getClass().getName() to see the object's actual
class.

/gordon

--
 
W

www

Hi,

I have two classes: State and WarmState.

public class State
{
... //many fields
}

public class WarmState extends State
{
... //more fields
}


Now, I have a State reference state, whose corresponding object was
created and filled. I believe/guess/thought it is a WarmState object.
Now I need to pass state to a method which only take WarmState
parameter. So I cast state to WarmState type. But I ran into
ClassCastException. Like I said, state was created and loaded from a xml
file. I hope to find out what caused ClassCastException. But neither of
these gave me a clue:

e.getMessage()
e.getLocalMessage()
e.printStackTrace()

Thank you for your help.
 
M

Mark Rafn

I have two classes: State and WarmState.
public class State
{
... //many fields
}
public class WarmState extends State
{
... //more fields
}
Now, I have a State reference state, whose corresponding object was
created and filled. I believe/guess/thought it is a WarmState object.

Why did you guess? In general, you should keep the specific type if you
need it to be specific, so you can't make this mistake. If you need something
that may or may not be a WarmState, then checking with the instanceof operator
before the cast is a good idea. Or use the Visitor pattern
(http://en.wikipedia.org/wiki/Visitor_pattern) to dispatch to the
subclass-specific handler.
Now I need to pass state to a method which only take WarmState
parameter. So I cast state to WarmState type. But I ran into
ClassCastException. Like I said, state was created and loaded from a xml
file. I hope to find out what caused ClassCastException. But neither of
these gave me a clue:

In jdk1.5 and newer (maybe jdk1.4, I can't remember), the message for the
ClassCastException should include the type of the object on which the cast
was attempted. Older versions didn't, and you have to put it under a debugger
or add debugging code.
e.getMessage()

If this doesn't give you something like: "your.package.State", you're running
an old VM, or something else is strange.

The following code:
public class ClassCast {
public static void main(String[] args) throws Exception {
Object o = new Object();
try {
System.out.println((String)o);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
shows this for me:
[dagon tmp]$ java -version
java version "1.5.0_12"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_12-b04)
Java HotSpot(TM) Server VM (build 1.5.0_12-b04, mixed mode)
[dagon tmp]$ java -cp . ClassCast
java.lang.Object
 
D

Daniel Pitts

www said:
Hi,

I have two classes: State and WarmState.

public class State
{
... //many fields
}

public class WarmState extends State
{
... //more fields
}


Now, I have a State reference state, whose corresponding object was
created and filled. I believe/guess/thought it is a WarmState object.
Now I need to pass state to a method which only take WarmState
parameter. So I cast state to WarmState type. But I ran into
ClassCastException. Like I said, state was created and loaded from a xml
file. I hope to find out what caused ClassCastException. But neither of
these gave me a clue:

e.getMessage()
e.getLocalMessage()
e.printStackTrace()

Thank you for your help.
<sscce>
public class Main {
static class Foo {}
static class Bar {}

public static void main(String[] args) {
Object o = new Foo();
Bar bar = (Bar)o;
}
}
</sscce>
<output>
Exception in thread "main" java.lang.ClassCastException: Main$Foo cannot
be cast to Main$Bar
at Main.main(Main.java:7)
</output>
That quite clearly says I'm trying to illegally cast a Foo to a Bar.
What is YOUR exception message say?
 
L

lord.zoltar

Hi,

I have two classes: State and WarmState.

public class State
{
... //many fields

}

public class WarmState extends State
{
... //more fields

}

Now, I have a State reference state, whose corresponding object was
created and filled. I believe/guess/thought it is a WarmState object.
Now I need to pass state to a method which only take WarmState
parameter. So I cast state to WarmState type. But I ran into
ClassCastException. Like I said, state was created and loaded from a xml
file. I hope to find out what caused ClassCastException. But neither of
these gave me a clue:

e.getMessage()
e.getLocalMessage()
e.printStackTrace()

Thank you for your help.

You can always print the names of the object's classes with
someObject.getClass().getName();

Personally, I always find these problems are easier to solve when
stepping through with a debugger. Hopefully, you have that option.
 
W

www

Thank you all.

Yes, I printed out "state.getClass().getName()" and it is type State. I
see what my problem is.

I have another related question. Suppose:

public class State
{
public Map<String, int> map = new Map<String, int>(); //please let me
use "public" here, the reason is to show my question below

private int numA;

public State()
{
setNumA(99);
}

public void setNumA(int a)
{
map.put("A", a);
}

}

public class WarmState extends State
{
private int numB;

public WarmState()
{
super();
setNumB(11);
}

public void setNumB(int b)
{
super.map.put("B", b);
}

}

With two classes above available, now:

State state = new State();

state.map.put("B", 33);

Can I cast state to type WarmState now?

Thank you.
 
D

Daniel Pitts

www said:
Thank you all.

Yes, I printed out "state.getClass().getName()" and it is type State. I
see what my problem is.

I have another related question. Suppose:

public class State
{
public Map<String, int> map = new Map<String, int>(); //please let
me use "public" here, the reason is to show my question below

private int numA;

public State()
{
setNumA(99);
}

public void setNumA(int a)
{
map.put("A", a);
}

}

public class WarmState extends State
{
private int numB;

public WarmState()
{
super();
setNumB(11);
}

public void setNumB(int b)
{
super.map.put("B", b);
}

}

With two classes above available, now:

State state = new State();

state.map.put("B", 33);

Can I cast state to type WarmState now?

Thank you.
There are two concepts for type that I think you're confusing...
Runtime type and Compile-time type.

You can not change the runtime type of an object once it has been
created (new State() creates a State instance), Casting *only* changes
the compile-type type information (what the compiler sees).
 
L

Lew

Daniel said:
There are two concepts for type that I think you're confusing...
Runtime type and Compile-time type.

You can not change the runtime type of an object once it has been
created (new State() creates a State instance), Casting *only* changes
the compile-type type information (what the compiler sees).

To state Daniel's point a little differently, in hopes that you can
triangulate on the concept, a variable has a compile-time type, and an object
itself has a run-time type. You can refer to an object via a variable of a
superclass (or super-interface) compile-time type.

Super something = new Sub();

For example,

List <String> data = new ArrayList <String> ();

List is a supertype of ArrayList. The object pointed to by the variable data
is still of type ArrayList, but the variable is of type List.

Now consider the inverse:

javax.management.AttributeList attributes = new ArrayList <Object> ():

Oops. You can't do that, because the object created by 'new' is a supertype
of AttributeList.

So therefore this will also fail:

ArrayList <Object> stuff = new ArrayList <Object> ();
javax.management.AttributeList attributes =
(javax.management.AttributeList) stuff;

Oops. Illegal cast.

<http://java.sun.com/javase/6/docs/api/javax/management/AttributeList.html>
<http://java.sun.com/javase/6/docs/api/java/util/ArrayList.html>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top