当前位置: 首页 > 面试题库 >

为什么要ClassCastException而不是编译错误?

沈乐邦
2023-03-14
问题内容

为什么在下面的代码中没有出现编译错误?我得到一个ClassCastException有点混乱的地方。是因为它们有关系吗?

class Ink {}

Interface Printable {}
class ColorInk extends Ink implements Printable {}

class BlackInk extends Ink {}


class TwistInTaleCasting {
   public static void main(String args[]) {
       Printable printable = null;
       BlackInk blackInk = new BlackInk();
       printable = (Printable)blackInk;
   }
}

问题答案:

为什么在下面的代码中没有出现编译错误?

因为编译器只关心您要强制转换的表达式的静态类型。

看这两行:

BlackInk blackInk = new BlackInk();
printable = (Printable)blackInk;

知道在第二行中,由于第一行,该值blackInk仅引用类型的对象BlackInk,而编译器则没有。对于所有的编译器知道(编译第二线时),它
可能 实际上已经:

BlackInk blackInk = new PrintableBlackInk();
printable = (Printable)blackInk;

…哪里PrintableBlackInk有扩展BlackInk和实现的类Printable。因此它是有效的(在编译时),以铸造从类型的表达式BlackInkPrintable。如果你做BlackInk一个final类,那么编译器知道有没有
办法 ,这将工作(除非值为null),并会在编译时失败,就像这样:

error: inconvertible types
          printable = (Printable)blackInk;
                                 ^
required: Printable
found:    BlackInk

其详细信息在JLS
5.5.1中

否则,我们 必须 等到执行时才能看到失败,因为强制转换在编译时有效。



 类似资料:
  • 问题内容: 遇到一个错误地使用 而不是 在其代码中的人,它没有显示为编译错误。 是因为 是相同的 ? 问题答案: 没有编译错误,因为它是有效的(尽管相当无用) 一元运算符 ,其使用方式与以下方式相同: Java语言规范中的相关部分是Unary Plus运算符+(第15.15.3节) 。它指定调用一元运算会导致操作数的一元数值提升(第5.6.1节)。这意味着: * 如果操作数是编译时类型的,,,或,

  • 问题内容: 如果你给 它没有编译,但是带有花括号的相同代码是: 有什么解释? 问题答案: 基本上,变量声明只能在块中声明。 查看 Java语言规范中“语句”的语法 -它包括Block,但不包括LocalVariableDeclarationStatement- 后者是block语法的一部分。 这实际上是实用主义的问题:如果没有括号,则只能使用一个语句。如果没有后续语句,则声明变量是没有意义的,因为

  • 本文向大家介绍什么是预编译,何时需要预编译:相关面试题,主要包含被问及什么是预编译,何时需要预编译:时的应答技巧和注意事项,需要的朋友参考一下 1、总是使用不经常改动的大型代码体。 2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

  • 问题内容: 下面的代码可以快速编译和运行。 我希望这是一个编译错误,因为结构永远不能符合AnyObject。如以下通过无法编译的代码所示。 我知道某些类型(例如String)可能会发生桥接。这将转换引用类型的值类型。 在写这个问题时,我想知道投射对象的类型是什么,似乎它也以某种方式被桥接。 为什么允许这种类型的铸造?似乎期望引用类型的函数违反了约定。 在重构一些代码以支持值类型时,我偶然发现了这一