I wonder if anyone could tell me how casting works? I understand when I should do it, but not really how it works. On primitive data types I understand partially but when it comes to casting objects I don't understand how it works.
How can a object with the type Object just suddenly be cast to, let's say,
Casting in Java isn't magic, it's you telling the compiler that an Object of type A is actually of more specific type B, and thus gaining access to all the methods on B that you wouldn't have had otherwise. You're not performing any kind of magic or conversion when performing casting, you're essentially telling the compiler "trust me, I know what I'm doing and I can guarantee you that this Object at this line is actually an <Insert cast type here>." For example:
Object o = "str"; String str = (String)o;
The above is fine, not magic and all well. The object being stored in o is actually a string, and therefore we can cast to a string without any problems.
There's two ways this could go wrong. Firstly, if you're casting between two types in completely different inheritance hierarchies then the compiler will know you're being silly and stop you:
String o = "str"; Integer str = (Integer)o; //Compilation fails here
Secondly, if they're in the same hierarchy but still an invalid cast then a
ClassCastException will be thrown at runtime:
Number o = new Integer(5); Double n = (Double)o; //ClassCastException thrown here
This essentially means that you're violated the compiler's trust. You've told it you can guarantee the object is of a particular type, and it's not.
Why do you need casting? Well, to start with you only need it when going from a more general type to a more specific type. For instance,
Integer inherits from
Number, so if you want to store an
Integer as a
Number then that's ok (since all Integers are Numbers.) However, if you want to go the other way round you need a cast - not all Numbers are Integers (as well as Integer we have
Long, etc.) And even if there's just one subclass in your project or the JDK, someone could easily create another and distribute that, so you've no guarantee even if you think it's a single, obvious choice!
Regarding use for casting, you still see the need for it in some libraries. Pre Java-5 it was used heavily in collections and various other classes, since all collections worked on adding objects and then casting the result that you got back out the collection. However, with the advent of generics much of the use for casting has gone away - it has been replaced by generics which provide a much safer alternative, without the potential for ClassCastExceptions (in fact if you use generics cleanly and it compiles with no warnings, you have a guarantee that you'll never get a ClassCastException.)