I am trying this piece of code. Why do I get ClassCastException
when I have initialized my set to contain elements of type Object
which is directly or indirectly parent of all classes in Java?
Set s = new TreeSet<Object>();
s.add(10);
s.add("ABC");
System.out.println(s);
According to the Treeset
javadoc, if you don't supply a Comparator
when creating the TreeSet
, it will use the element's natural ordering. That means that to determine the ordering of a pair of values, it will cast one value to Comparable<?>
and then call compareTo
to compare it to the other one.
In your example, the cast to Comparable<?>
actually works, because both classes implement Comparable
, albeit with different type parameters.
The problem is that this.compareTo(v)
is defined to throw a ClassCastException
when this
and v
are not comparable. The javadoc says:
"Throws:
ClassCastException
- if the specified object's type prevents it from being compared to this object."
When a
is Double(10)
and b
is "ABC"
and you call a.compareTo(b)
, the Double.compareTo
method will attempt to cast b
to Double
. That cast will throw a ClassCastException
.
In short, if you want to use a TreeSet
to hold a mixture of different types, you must define and supply a Comparator
that can order all of the types / elements you are going to add to the set.