我在解释中添加了一个子类。
Tree
/ \
/ \
/ \
Redwood Blackwood
在这个层次结构中:
向上转型:
当我们沿着类层次结构将引用从子类向根方向转换时。 在这种情况下,我们不需要使用转换运算符
向上转型示例:
Redwood
或Blackwood
都是tree
:因此
Tree t1;
Tree t2;
Redwood r = new Redwood() ;
Blackwood b = new Blackwood() ;
t1 = r; // Valid
t2 = b; // Valid
Downcast:
向类层次结构中从根类(父类)指向子类(或者子类的子类)的方向进行引用转换时,我们需要进行显式类型转换。
Downcast Example:
Redwood r = new Tree()
Blackwood r = new Tree()
如果一个 Tree 对象
真的指向了 Redwood
或者 Blackwood
对象,那么你需要显式地进行类型转换,否则会在运行时出错。例如:
在这个例子中:
Tree t1;
Tree t2;
Redwood r = new Redwood() ;
Blackwood b = new Blackwood() ;
t1 = r; // Valid
t2 = r; // Valid
Redwood r2 = (Redwood)t1;
Blackwood b2 = (Blackwood)t2
[答案]
为什么没有编译器错误?这是向下转型的示例:
源代码Redwood r = (Redwood) new Tree();
首先创建Tree对象,然后将其强制类型转换为Redwood
。
您可以这样考虑:
Tree t = new Tree()
Redwood r = (Redwood)t
所以在编译时没问题,但是为什么会出现运行时错误呢?实际上,Redwood
子类不能指向 Tree
父类对象。因此你的代码在运行时失败了。
Tree t = new Tree();
t
指向的是 Tree()
对象而不是 Redwood()
。这就是运行时错误的原因。
编译器不知道 t
中的值,在语法上一切都正确。但是在运行时由于 Redwood r = (Redwood)t;
,其中 t
是 Tree class
的一个对象,它变得有缺陷了。
[建议:]
我想建议您使用 instanceof 运算符:
强制转换操作用于在类型之间进行转换,而 instanceof 运算符用于在运行时检查类型信息。*
描述:
instanceof 运算符允许您确定对象的类型。它将对象放在运算符的左侧,类型放在运算符的右侧,并返回一个布尔值,指示对象是否属于该类型。以下是最清晰的示例:
if (t instanceof Redwood)
{
Redwood r = (Redwood)t;
// rest of your code
}
但我想补充一点:将基本类型转换为派生类型是不好的事情。
参考资料: 小心instanceof运算符