【问题标题】:Java Narrowing Reference Conversion from a type to an interface从类型到接口的 Java 缩小引用转换
【发布时间】:2019-01-15 22:03:00
【问题描述】:

试图理解从类到接口的java缩小转换。 JLS(JLS-5.1.6) 声明:

从任何类类型 C 到任何非参数化接口类型 K,前提是 C 不是 final 且不实现 K。

为了测试这一点,我创建了一个类和一个接口。然后尝试将类转换为接口,但得到一个运行时 ClassCastException。这是我的代码示例。

class NarrowingReferenceConversion
{
    public static void main(String args[])
    {

        S s = new S();
        T t = (T)s;

    }
}

interface T
{
    public void print();
}

class S
{
    public void print(){
        System.out.println("S.print()");
    }
}

在编译和运行上述代码时,我收到以下错误消息:

线程“main”java.lang.ClassCastException 中的异常:S 不能转换为 T

【问题讨论】:

  • 你的类 S 应该实现接口 T。在这种情况下,转换会成功。
  • 在5.1.6的末尾有:"这样的转换需要在运行时进行测试,以确定实际的引用值是否是新类型的合法值。如果不是,那么一个ClassCastException被抛出。"

标签: java casting type-narrowing


【解决方案1】:

这是一种不能保证有效的转换,就像不能保证将基类的引用转换为子类一样。这就是为什么它被视为缩小转换。

编译器知道转换可能在运行时起作用,所以它允许它,但如果它不起作用,ClassCastException 在运行时被抛出。

仅当您为 s 分配一个实现接口 TS 子类的实例时,转换才会起作用。

class NarrowingReferenceConversion
{
    public static void main(String args[])
    {

        S s = new S2();
        T t = (T) s; // this will work, since S2 implements T

    }
}

interface T
{
    public void print();
}

class S
{
    public void print(){
        System.out.println("S.print()");
    }
}

class S2 extends S implements T
{
}

我们来解释一下这个转换的两个条件:

  1. “C is not final”——如果是final,就没有C的子类,所以编译器肯定知道这个转换永远不会成功,编译失败。

  2. “不实现 K” - 如果 C 实现 K,则这不再是缩小转换。它变成了Widening Reference Conversion,保证在运行时成功。事实上,没有必要使用强制转换运算符。一个简单的任务就可以了。

【讨论】:

    【解决方案2】:

    简单的事情是:

     S s = new S();
     T t = (T)s;
    

    鉴于您显示的当前代码,编译器可以知道这种转换没有意义,并且必须在运行时失败.

    但问题是:您的案例是一个非常具体的例子。常见的用例不太“清楚”。如 Eran 所示,构建一个类似的示例非常简单,在该示例中,运行时的强制转换可能有效,也可能无效,具体取决于非常细微的差异。

    因此,务实的答案是:编译器可以知道程序无效并且稍后会失败的事实并不一定会导致编译器失败。

    换句话说:当您设计语言并构建编译器时,总是需要权衡取舍。如:有时在编译时添加一个非常具体的检查是不值得的。您宁愿接受一个更通用的规则,该规则可能导致运行时而不是编译时失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      • 2011-04-22
      • 2021-07-22
      • 2019-12-12
      • 2014-05-03
      相关资源
      最近更新 更多