• Post Reply Bookmark Topic Watch Topic
  • New Topic

ArrayList - Casting Object References  RSS feed

 
leo donahue
Ranch Hand
Posts: 327
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ArrayList list = new ArrayList();
Dog d = new Dog();
Cat c = new Cat();
Frog f = new Frog()
list.add(d);
list.add(c);
list.add(f);
Knowing that when you add object references to an ArrayList, they go into the ArrayList as the object you reference, but come out as plain old object.
Then how does the compiler know when you try to cast an object from the ArrayList as the wrong type of object, but it "freaks" when you try to call a method on an index you know is of a certain type object?
What's the deal?
 
john smith
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
//Then how does the compiler know when you try to cast an object from the ArrayList as the wrong type of object,
It doesn't. The only knowledge avaliable at compile-time of the type of object in any Collection is that will beof the type java.lang.Object. Object type info is only avaliable at run-time.

//but it "freaks" when you try to call a method on an index you know is of a certain type object?
The compiler will "freak" if you try to call any method on an object returned from a Collection that is not avaliable to a java.lang.Object, unless you cast it to the correct object type. *You* know it is of a certain type (that why you can confidently cast it) but the compiler will assume it is an Object, unless you tell it differently with an explicit cast.
 
Jeroen Wenting
Ranch Hand
Posts: 5093
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Then how does the compiler know when you try to cast an object from the ArrayList as the wrong type of object, but it "freaks" when you try to call a method on an index you know is of a certain type object?
The compiler doesn't know and will happily allow the following:

This will give you a host of ClassCastExceptions at runtime, but the compiler won't complain as long as Cat has a method chase(Mouse) and Dog a method scare(Cat).
 
leo donahue
Ranch Hand
Posts: 327
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's what I meant to say, at runtime.
How can the compiler compile something so that the runtime environment knows what object is really in the ArrayList, but the compiler doesn't?
I know the compiler decides whether you can call a method based on
the reference type and not the acutal object type.
But the compiler must mark those objects, in an ArrayList, somehow
in order for the ClassCastExceptions to work.
Is it because of polymorphism?
 
Wayne L Johnson
Ranch Hand
Posts: 399
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is a difference between the object (class) type and the referent type of that object. As the previous posters have explained, the compiler is very strict and so it goes by the referent type, whereas run-time goes by the actual object type.
So in the code:

The compiler--being strict--makes sure that you don't call any method on the "foo" object that isn't defined in java.lang.Object. But at run-time--because of polymorphism--the JVM can see that the object is actually something of type "Bar". So if the class "Bar" has overridden the "toString()" method, that's the version that will be called.
Looking at this simple example and the ones provided in the previous posts, it seems like the compiler should "know" that "foo" is really of type "Bar", and not simply "Object". But most examples are not this easy. You may be reading the Java objects in from a serialized stream, or maybe they are being returned from a "Factory" method that is creating them based on some input. So if you have something like:

You may know that what's stored in the file is a bunch of "Bar" instances, but the compiler has no way of knowing if that file exists or what it contains. So it only allows method calls that corresponds to the referent type. If you want something else, you have to do an explicit cast to the appropriate type.
However at runtime the JVM can interrogate the object and find out what type it actually is. Every object "knows" what it really is. But the objects don't exist at compile time.
Confusing enough ;-)
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!