1

Ive read a number of other questions on these pages about the class cast exception, and I want to be sure that my problem is essentialy the same thing (ie related to not knowing the bound type of the class during run time compared with during compile time).

so here is my test class....

public class testCastReturn{
    public test(){

       HashSet<String> StringHash; //a simple hash set

       HashMap(<String, ComplexObject> ObjectInfo; //the String value is the name of the complexObject, and complexObject has multiple members (in this instance it is a java model for a database field so it has info pertaining to Key, size etc)

       //create a ComplexObject here
       addToObjectInfo(aComplexObject); // add it into the HashMap

       //repeat above a number of times....
       //now collect the 'names' of those objects
       StringHash = getObjectKeys();
    }

    public void addToObjectInfo(complexObject c){
        //put a complex object into the HashMap

        ObjectInfo.put(c.getNameID, c); //create a set of key value pairs where the name of the object is the key to get the actual object
    }

    public HashSet<String> getObjectKeys(){
       //retrieve the keys only
       return HashSet<String> this.ObjectInfo.keySet(); //fails with classCastException
       //this however works
       HashSet<String> temp = new HashSet<String>(this.ObjectInfo.keySet());
       return temp;   
    }  
 }//end class

If my understanding is correct this is why I can compile my code in either form, but I can only run the code where I explicity create a temp place to hold the keyset because as run time the JVM can't guarantee what the bound type of the keys are going to be in the ComplexObject. Please bear in mind that this is contrived version so may have oversimplified it, in my actuall code I am using a 'builder' and then passing the information to the 'finalised' class, and then a bunch of these classes are held within a third object that has the HashMap of ComplexObjects.

If you require any further info please ask (I can even send a copy of my library if you wish).

David

2
  • frankly, i cannot understand your problem. You have simplified the code, but compounded your explanation :) Commented May 23, 2012 at 12:45
  • @Krishnanunni indeed, I was just trying to be helpfull so as others would realise I was into something a little more complex, in case the 'contrived' example is somehowe related to my own setup (ie, the builder class is actually called from another package, and this problem came to light during my JUnit testing - so +1 to testing!) Also I want to confirm I am understanding correctly, thinking I understand when I don't is, in my experience, a potential for later dissaster. That said however, I also need to learn to just 'get on with it' (ie understanding pointers in C). Commented May 23, 2012 at 13:16

2 Answers 2

4

keySet() returns a Set, not HashSet. So return this.ObjectInfo.keySet(); should do.

A rule of thumb: always refer to collections (and object in general) by their interface, rather than their class. So prefer List and Set to ArrayList and HashSet. Use the concrete types only when you instantiate the objects or whenever you need some feature specific to the concrete implementation.

Sign up to request clarification or add additional context in comments.

1 Comment

Oh ok, so I can return a set from this method and it will be accepted by my HashSet object. Because the Set is the interface and the HashSet has to implement all of its methods. My understanding has just improved thanks. I originally thought that a hashSet was a child of the set class (I should have looked more closely as the docs).
1
public Set<String> getObjectKeys(){
   return this.ObjectInfo.keySet();
}

would this work for you?

1 Comment

I did think of that that, but this is not how my original code was written, and so I wanted to understand my original code. Also the HashSet is used in other methods and would have required a more complex refactoring.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.