当前位置: 首页 > 知识库问答 >
问题:

为什么它在转换到不相关的接口时编译?[重复]

韩飞翮
2023-03-14
interface Printable {}
class BlackInk {}

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

如果编译并运行前面的代码,结果是printable=(printable)blackInk处的ClassCastException 。但是,如果将Printable更改为类,它就不会编译,因为blackInk不能转换为Printable。当Printable是一个接口时,它为什么要编译?


共有3个答案

童铭晨
2023-03-14

类型转换发生在运行时(记住运行时多态性)。在编译时,编译器没有发现代码有任何错误,并进行编译,在运行时,它试图将castblackink键入printable,但无法执行,因为blackink没有实现printable,因此出现错误。

鲁财
2023-03-14

根据java语言规范部分:5.5.1参考类型铸造:

对于编译时引用类型S(源)和编译时引用类型T(目标);当从S转换为T时,如果S类型

>

  • 如果TClass类型:

    >

    class S{}
    
     class T extends S{}
      ////
    
      S s = new S();
      T t = (T)s; // run time ClassCastException will happen but no compile time error
    

    如果T接口类型:

    1. 如果S不是final类,那么,如果存在T的超类型X,以及S的超类型Y,那么XY都是可证明的不同参数化类型,XY的擦除是相同的,出现编译时错误。否则,cast在编译时总是合法的(因为即使S没有实现TS的子类也可能实现)

    对于您的情况,即使在编译时检测到类转换,也会在运行时中检测到Interface转换。

  • 滕项明
    2023-03-14

    编译器不知道这是行不通的:您可能有一个子类BlackInk,它实现了可打印。那演员就没事了。

    在编译器知道它无法工作的情况下,您将得到一个错误。

    例如,如果将BlackInk设置为final(这样就不会有子类),则会出现错误。

     类似资料:
    • 问题内容: interface Printable {} class BlackInk {} 如果前面的代码已编译并运行,则结果为ClassCastException 。但是,如果将Printable更改为一个类,则因为blackInk无法转换为Printable而无法编译。当Printable是接口时,为什么要编译? 问题答案: 编译器不知道这是行不通的:您可能具有实现Printable的Bla

    • 问题内容: 显然,这会导致编译错误,因为Chair与Cat无关: 为什么当我将Cat引用转换为不相关的接口Furniture时,我只能在运行时得到一个异常,而编译器显然可以告诉Cat没有实现Furniture? 问题答案: 编译的原因 是你可能会拥有 如果创建实例,则可以将其分配给,并且可以将该实例强制转换为。换句话说,某些子类型可能会实现该接口。 在第一个例子中 除非自身从扩展,否则某些子类型不

    • 显然,这会导致编译错误,因为椅子与Cat无关: 那么,为什么只有在运行时,当我将Cat引用转换到不相关的接口家具时,才会出现异常,而编译器显然可以看出Cat没有实现家具?

    • 问题内容: 因此,如果我有一个,由于某种原因,如果我在另一段代码(如)中引用它,则在编译过程中它不会内联到代码中。因此,它不是在被编译之后而是。 问题答案: 您不是编译时间常数,因为JLS 表示 不是。只能在常量表达式中使用的类型是基本类型和。 它的意义是,一个实例(通常)具有语义上重要的对象标识,该标识将其与其他实例区分开。此对象标识不能编码在类文件中……至少,不能用当前的类文件格式编码。(如果

    • 问题内容: 我正在尝试使用泛型实现以下结构。收到编译器错误,无法找出原因。 这个想法是译者使用T作为字典中键的类型。例如,可以是字符串或枚举。子类提供具体的字典。 但是它失败,因为:“类型’String’不符合协议’Hashable’” 但是String符合Hashable。它也不适用于Int,后者也符合Hashable。 如果删除类型约束,则仅用于测试(在此我还必须禁用字典,因为我不能在其中使用

    • 我有一个简单的测试设置,如 但当我尝试编译测试时,我会遇到53个错误,比如 实际上并没有传达任何关于问题所在的有用信息。我只能假设在我的构建中没有正确配置某些内容。sbt文件或其他地方。 这段代码确实曾经工作过,在我清理东西的过程中,事情发生了变化,现在它被破坏了,没有好的诊断。 有人能提出要找的东西吗?