Maybe I'm simplifying too much, but "strong typing" basically means "every variable has a type which is known at compile time".
Now for casting: an expression has a type, but it might not be known at compile time. That's not in conflict with strong typing because variables and expressions are different things. Consider this simple code:
You'll notice that both of the variables have declared types, Java requires that. But as you know, that code won't compile because all the compiler knows is that the expression abc is of type Object and therefore can't just be assigned to a String variable. That would violate strong typing.
But that expression abc is a reference to a String object. You and I know that but the compiler doesn't. So we can cast it:
And now the compiler is happy.
(Remember I said that variables and expressions are different things? That code fragment uses abc in two places. The first one declares the variable abc, and the second one is the expression abc, which is the contents of the variable. It's easy to get those two concepts mixed up.)
Oh no... There is also casting between primitive types, like in the W3Schools example there. But that's a different thing completely compared to the casting example I gave in my previous post. The reason that primitive casting exists is much the same, though; the compiler might have a double value being assigned to an int variable. Again the compiler is holding your hand and saying "I think you might not be able to assign this double value to that int variable without problems." And you're entitled to do a cast to say that you expect it will be okay.
Paul Clapham wrote:. . . casting between primitive types . . . a different thing completely . . . ". . . you might not be able to assign this double value to that int variable without problems." And you're entitled to do a cast to say that you expect it will be okay.
Agree that casting primitives is so different from casting reference types that it is bad that both actions have such similar names. When you cast a primitive, however, it is not a case of saying you expect it will be okay. It is a case of telling the compiler, “Look, I want an int and I expect you to fit that double into it, even if you have to change its value.” Much more definite. A primitive cast either won't compile or it will run to completion normally. It will never throw an exception.
One of the best things about Java versus C/C++ is how casting works in Java. In C or C++, you can cast anything to anything, and the compiler may or may not convert the data format. In the case of objects, in particular, you can cast a pointer to a "foo" as a pointer to a "bar" and no problems. Until you run the code and it explodes because foos don't look anything at all like bars.
In Java, the casting rules are much more strict and if you attempt an incompatible cast, you'll get a compile-time error. You can still get into trouble when casting, but you'll get into a lot less trouble.
As much as possible, you should avoid casting at all. In the case where, for example, a generic type of plugin is designed to work on a particular subclass of a generic base class object, that would be a case for up-casting. But properly paranoid code would do an "instanceof" check before doing the actual cast, to avoid problems.
"privilege" comes from the Latin words for "private" and "law" (legal) and dates to feudal times. To "claim privilege" meant that you were above the laws that applied to the common people.