Casting is a process by which you interpret certain data differently than what is says in the label. To continue with that same analogy: casting is like changing the label on a jar without changing the contents – and acting as if what the label said was the absolute truth.
The behavior varies with primitive data types and Objects, which are the composite data type Java functions with. So let’s get primitive data types out of the way:
Numeric types can be casted into other numeric types; the way they’re stored in memory is changed, and data may be lost when casting from a type with more memory to a type with less memory. Characters (char) and bytes count as numeric types for this case. Booleans (boolean) can’t be casted. More nuances can be picked up from the docs, particularly if you see table 5.1.
String is not there for a reason – it falls in the Object classification, and not the primitive data type classification.
Let’s get some nomenclature out of the way to avoid confusion.
Composite types in Java are created with classes, which are a blueprint for how data is laid out + operations grouped with the data (a class can be considered a data type). A particular instance (or building made from that blueprint) is an Object. So, what you cast is an object, which is created by following a blueprint called a class.
Class = blueprint (or recipe?), Object = building (or hopefully delicious food!).
Those analogies are imperfect, don’t take them too far. But they’ll hold for a bit.
So, when you define a class, you’re doing much of what the people who built the language made for primitive data types: you’re stating what data is going to be there, how it is to be laid out, and a developing a set of operations that can have privileged access to the data in a way that developers using the types may not have.
Cool? Cool. Now, back to casting: to get a data type to morph into another, they need to be somewhat compatible. There’s a particular type of casting called boxing and unboxing which go from a primitive type to an object which handles the primitive type. This is useful for some reasons we’ll talk about in the future, just be content to know that this happens.
In order for you to have a good handle of type correspondence: int => Integer is the only odd one. The rest of equivalent object types are called the same as primitive data types with capitalized name (boolean => Boolean). These work implicitly much of the time, basically because language designers decided it was good enough that way – this reminds me a bit of the shenanigans that go on with the String type. In any case, it allows you to mix and match primitives and objects and use operators just as if they were primitives, or objects. This is, I think, ugly.
So, yeah, boxing and unboxing happen automagically.
Having covered those, and with you having hopefully taken a look at my post on data types, I want to tackle the last bit about casting: casting between composite types.
If you paid any attention, you may remember that casting only works between types with compatible data, and that some information may be lost when doing the casts. In the case of composite data types, it’s not easy to transform between them, so the computer must know beforehand what the relationship is between the two types you’re using in the cast. The how of it is a topic for the near future… just remember that casts happen automatically when you signal them – you don’t need to write code to specify what to do with each particular datum, only that you want this to behave as if it were that.
If you paid a bit more attention, you may have noticed that classes contain operations. Different classes may have not only different data, but different operations, so what you can do with a particular collection of data is dependent on how you’re choosing to treat it. You can have a different set of operations available, usually fewer than the original type, or the same amount of operations, as well as data availalble, when you perform a cast.
What’s the cast syntax, you ask? This series is about Java, you say?
RandomType variableName = (RandomType)aRandomVariable;
This series is mainly about insights. Practical advice is easily found elsewhere. That’s why so much verbiage, so little code. But if you have any particular questions, don’t hesitate to ask. Worst case scenario is I can’t answer your query, and that’s not so bad, seeing as you already don’t have my answer.