javaoopcollectionsclasscastexception

Why do I get ClassCastException?


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);

Solution

  • 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.