Java 强制转换是否在运行时更改声明/引用类型?
首先,让我明确声明的类型是什么意思。 假设SuperBoss是类Boss的超类Java 强制转换是否在运行时更改声明/引用类型?,java,casting,runtime,Java,Casting,Runtime,首先,让我明确声明的类型是什么意思。 假设SuperBoss是类Boss的超类 SuperBoss mrBond = new Boss(); SuperBoss是声明的类型,Boss是实际的类型 我个人认为,由于以下运行时异常,声明的类型在运行时被更改: SuperBoss mrWayne = new SuperBoss(); ((Boss)mrWayne).randomMethod(); //Exception: java.lang.ClassCastException: SuperBo
SuperBoss mrBond = new Boss();
SuperBoss是声明的类型,Boss是实际的类型
我个人认为,由于以下运行时异常,声明的类型在运行时被更改:
SuperBoss mrWayne = new SuperBoss();
((Boss)mrWayne).randomMethod();
//Exception: java.lang.ClassCastException: SuperBoss cannot be cast to Boss
我知道这可能看起来很琐碎,但我下个季度要做家教,我不想教学生错误的东西。我的教授和她的助手在这个问题上意见不一致。我的教授认为,对于一条语句,强制转换确实完全改变了运行时声明的类型。T.A.坚信在运行时,强制转换只是被检查,但实际上并没有改变声明的类型
我的教授认为,对于一条语句,强制转换确实完全改变了运行时声明的类型。T.A.坚信在运行时,强制转换只是被检查,但实际上并没有改变声明的类型
事实上,我认为他们在某种意义上都是对的。他们所说的并不矛盾。。。如果你能弄清楚他们到底在说什么
mrWayne
的声明类型不会更改。声明的((Boss)mrWayne)
类型不“更改”。或者至少,它与声明的mrWayne
类型不同
这里真正的问题是有人在使用草率的术语。。。人们在谈论彼此的过去
请考虑这个例子:
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);
}
}
这应该输出:
Its a test
Its an object
为什么??因为(Object)t
的声明类型是Object
。。。非测试
。并且是声明的类型(而不是运行时类型)决定了method
的两个重载中的哪一个用于特定调用
看到了吗
这完全取决于你在说什么。变量的声明类型或表达式的声明类型。声明的类型是您向编译器声明的类型。编译程序后,它不会改变
“运行时”类型是分配给变量的实际对象的类型。它仅在指定新对象时更改。(对于给定对象,它从不更改,任何对象实例都不能更改其类)
强制转换将两者连接起来:它检查运行时类型,然后允许您声明该类型。如果检查失败,程序将中止(运行时异常)。当您拥有比编译器更多的类型信息时,需要执行此操作。然后,您可以向编译器“声明”所讨论的对象确实是一个“Boss”,而不仅仅是一个“SuperBoss”(这是编译器能够保证的最好的方式)
我的教授认为,对于一条语句,强制转换确实完全改变了运行时声明的类型
强制转换在编译时“声明”一个更具体的类型。但它还包括一个运行时检查,以确保安全
T.A.坚信在运行时,强制转换只是被检查,但实际上并没有改变声明的类型
检查发生在运行时,但在代码中使用强制转换允许您在编译时进行更具体的类型声明
((Boss)mrWayne).randomMethod();
发生了两件事:
- 编译时:您声明这是一个Boss。否则您无法调用该方法
- 运行时:JVM检查该对象是否真的是Boss