Java 铸造有什么保护作用?

Java 铸造有什么保护作用?,java,casting,compiler-errors,Java,Casting,Compiler Errors,在该代码中,必须强制转换为条。我正试图了解它避免了什么问题。如果编译器允许我使用Foo作为Bar而不强制转换,那么它是否能够使用Bar可能具有的扩展功能?还是有更重要的原因?或者这个例子太琐碎了,无法解释我为什么要投 class Foo { } class Bar extends Foo { } public class Main { public static void main(String[] args) { Foo f1 = new Bar();

在该代码中,必须强制转换为
。我正试图了解它避免了什么问题。如果编译器允许我使用
Foo
作为
Bar
而不强制转换,那么它是否能够使用
Bar
可能具有的扩展功能?还是有更重要的原因?或者这个例子太琐碎了,无法解释我为什么要投

class Foo { }
class Bar extends Foo { }

public class Main {
    public static void main(String[] args) {
        Foo f1 = new Bar();
        Bar b1 = (Bar) f1;
    }
}

我们能不能写一个简单的例子,让我明白,如果我不投,就会有麻烦?我可以认为运行时不需要在上面的代码中进行强制转换就可以帮助自己,但我肯定还没有理解为什么我必须进行强制转换的深层细节

这可以保护您避免错误的施法。如果您想使用not casted类,它现在实际上是Bar类型,那么您希望在使用它的方法时看到什么?例如,您实际上将f1设置为Foo类型,然后尝试将Bar类型的b1设置为指向类Foo。您正试图从Bar调用方法,但并没有实现它。你期待什么?编译器也不会知道。在这种情况下,如果您试图强制转换错误的类,您将只获得
java.lang.ClassCastException
,我们知道如何保护它。

如果您将另一个类添加到层次结构中,强制转换的必要性将变得更加清楚。考虑一下这组类:

class Foo {}
class Bar extends Foo {}
class Baz extends Foo {}
现在,如果您有一个类型为
Foo
的引用,它可能引用
Foo
实例、
Bar
实例或
Baz
实例。考虑这个代码片段:

Foo f;
if (Math.random() > 0.5) {
    f = new Bar();
} else {
    f = new Baz();
}
您不能简单地将
f
称为
Bar
,因为在这种情况下,
f
可能不是
Bar
,而是
Baz
。因此,演员们基本上是在说,“我知道这可能会失败,但我有理由相信它不会成功,所以继续尝试吧。”。例如,我们可以执行以下操作:

Foo f;
if (Math.random() > 0.5) {
    f = new Bar();
} else {
    f = new Baz();
}

if (f instanceof Bar) {
    Bar b = (Bar) f;
    // do stuff with b...
}
if
块中,我们有理由相信
f
是一个
Bar
实例,尽管java编译器不能确定这一点。(在本例中,它看起来很简单,但可能有数千行和多个堆栈帧将
if
条件和强制转换分隔开)。因此,我们可以满怀信心地制作演员阵容


但是,如果您错误地认为强制转换实际上是无效的,那么在尝试强制转换的行上会出现
ClassCastException
。这使问题变得更清楚:在所讨论的实例没有所需功能的情况下,不是在随机行上获取异常,而是在尝试转换的地方发生异常。

最简单的示例:
1/2
将结果为0,除非将其中一个强制转换为双精度,因此在代码中
2/(1/2)
如果不强制转换,可能会出现异常。您应该看看Java,在这种情况下强制转换的是Java的概念。