Reputation: 1322
First, let me be clear about what I mean by the declared type. Assume SuperBoss is a superclass of the class Boss.
SuperBoss mrBond = new Boss();
SuperBoss is the declared type, and Boss is the actual type.
Personally, I think the declared type is changed at run-time due to the following run-time exception:
SuperBoss mrWayne = new SuperBoss();
((Boss)mrWayne).randomMethod();
//Exception: java.lang.ClassCastException: SuperBoss cannot be cast to Boss
I know this may seem trivial, but I'm going to be tutoring next quarter, and I don't want to teach the students the wrong thing. And my professor and her assistant this quarter did not agree with each other on this subject. My professor believes that casting does indeed completely change the declared type at run-time for a single statement. The T.A. strongly believed that at run-time, the cast is merely checked, but doesn't actually change the declared type.
Upvotes: 5
Views: 6881
Reputation: 718758
My professor believes that casting does indeed completely change the declared type at run-time for a single statement. The T.A. strongly believed that at run-time, the cast is merely checked, but doesn't actually change the declared type.
In fact, I think that they are both right in a sense. There is no contradiction in what they are saying ... if you can figure out what they are actually saying.
The declared type of mrWayne
does not change. The declared type of ((Boss) mrWayne)
does "change". Or at least, it is different to the declared type of mrWayne
.
The real problem here is that someone is using sloppy terminology ... and people are talking past each other.
OK consider this example:
public class Test {
public static void method(Object t) {
system.out.println("Its an object");
}
public static void method(Test t) {
system.out.println("Its a test");
}
public static void main(String[] args) {
Test t = new Test();
method(t);
method((Object) t);
}
}
This should output:
Its a test
Its an object
Why? Because the declared type of (Object) t
is Object
... not Test
. And it is the declared type (not the runtime type) that determines which of the two overloads of method
is used for a particular call.
See?
It all depends on what you are talking about. The declared type of the variable, or the declared type of the expression.
Upvotes: 5
Reputation: 262494
The "declared" type is what you declared to the compiler. It does not change after the program is compiled.
The "runtime" type is the type of the actual object assigned to a variable. It only changes when you assign a new object. (It never changes for a given object, no object instance can change its class).
The cast bridges the two: It checks the runtime type and then allows you to declare that type. If the check failed, the program will abort (with a RuntimeException). You need to do this when you have more type information then the compiler. You can then "declare" to the compiler that the object in question is indeed a "Boss", and not just a "SuperBoss" (which is the best the compiler could otherwise guarantee).
My professor believes that casting does indeed completely change the declared type at run-time for a single statement.
Casting "declares" a more specific type at compile-time. But it also includes a runtime check to make this safe.
The T.A. strongly believed that at run-time, the cast is merely checked, but doesn't actually change the declared type.
The check happens at runtime, but having the cast in your code allows you are more specific type declaration at compile-time.
((Boss)mrWayne).randomMethod();
Two things happen:
compile time: You declare that this is a Boss. Otherwise you couldn't call the method.
run time: The JVM checks if that object really is a Boss.
Upvotes: 2