【问题标题】:ClassCastException in Inheritance - Why?继承中的 ClassCastException - 为什么?
【发布时间】:2020-01-09 06:52:22
【问题描述】:

以下代码抛出ClassCastException

线程“main”中的异常 java.lang.ClassCastException: 类 Child 不能转换为类 java.util.List(孩子在未命名的模块中 加载器“应用程序”; java.util.List 在 loader 的模块 java.base 中 'bootstrap') 在 Test.main(Test.java:20)

我真的不确定它为什么会这样。我想我写的代码是正确的。

public class Test {
    public void a(ParentI... ss) {
    }

    public void a(List<ParentI> ss) {
    }


    public <R extends ParentI> R makeParent() {
        ParentI ai = new Child();
        return (R) ai;
    }

    public static void main(String[] args) {
        Test al = new Test();
        al.a(al.makeParent());
    }
}


interface ParentI {
    public void a();
}

class Parent implements ParentI {
    public void a() {
        System.out.println("Parent");
    }
}

class Child extends Parent {
    public void a(int t) {
        System.out.println("child");
    }
}

请帮助我理解这一点以及如何解决这个问题。

【问题讨论】:

  • 完整的堆栈跟踪和发生异常的行会很有帮助。
  • 请立即查看
  • 其他人有这个例外还是只有我,我正在取消 intellij
  • 仍然没有堆栈跟踪,也没有提示导致异常的行。
  • 异常是在al.a(al.makeParent());引起的

标签: java inheritance exception


【解决方案1】:

编译器根据方法重载决议选择的a() 方法推断al.makeParent() 返回的类型。

由于方法重载决议首先考虑没有可变参数的候选者,因此只考虑 public void a(List&lt;ParentI&gt; ss) 重载,因此这是选择的重载。

public void a(List&lt;ParentI&gt; ss) 可以接受返回R extends ParentI 的方法的返回值作为其参数的原因是可能存在一个扩展ParentI 并实现List&lt;ParentI&gt; 的类。

一旦选择了public void a(List&lt;ParentI&gt; ss) 重载,return (R) ai; 中的转换会导致尝试将Child 实例转换为List,但在运行时失败。

例如,如果您将Child 类的定义更改为:

class Child extends Parent implements List<ParentI>

您的代码将毫无例外地运行。

【讨论】:

    【解决方案2】:

    虽然我不知道为什么会抛出异常。我已经设法编辑代码,以便程序成功运行。 makeParent() 方法需要修改,所以它不是通用的:

    public ParentI makeParent() {
        ParentI ai = new Child();
        return ai;
    }
    

    基本上和以前一样。

    然后,调用正确的重载a()

    【讨论】:

      猜你喜欢
      • 2011-04-02
      • 2021-11-17
      • 2014-08-26
      • 2010-12-07
      • 1970-01-01
      • 2015-04-28
      • 2016-06-16
      • 2014-06-09
      • 1970-01-01
      相关资源
      最近更新 更多