You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java继承外部类及其内部类后遇类型转换异常问题求助

问题:继承外部类及内部类后类型转换异常的解决办法

问题场景

子类SMONArray继承外部类SMONArr的同时,也继承了其内部类Element,但在调用getSelected方法时出现类型转换错误:

  • 编译阶段提示Type mismatch: cannot convert from SMONArr.Element to SMONArray.Element
  • 强制转换后编译通过,但运行时抛出java.lang.ClassCastException: SMONArr$Element cannot be cast to SMONArray$Element

原代码

SMONArray 子类

public class SMONArray extends SMONArr {

    public class Element extends SMONArr.Element {
        protected int x, y, w, h;

        protected Element(String string, Object arr) {
            super(string, arr);
        }
    }

    public Element getSelected(String key, int index) {
        return get(key, index);
    }
}

SMONArr 父类

public class SMONArr {
    protected final LinkedHashMap<String, ArrayList<Element>> arr = new LinkedHashMap<>();
    public class Element {
        public String key;
        public Object elem;

        protected Element(String string, Object arr) {
            key = string;
            elem = arr;
        }
    }

    public Element get(String key, int index) {
        return arr.get(key).get(index);
    }
}

错误原因

父类SMONArr的arr集合中存储的是**SMONArr.Element实例**,而子类SMONArray.Element是它的子类类型。Java中父类对象无法直接强制转换为子类对象,因此运行时会抛出类型转换异常。

解决方案

方案1:给父类添加泛型支持(推荐)

修改父类为泛型类,让子类可以指定自己的Element类型,确保集合中存储的是子类的Element实例:

修改后的父类 SMONArr

public class SMONArr<E extends SMONArr.Element> {
    protected final LinkedHashMap<String, ArrayList<E>> arr = new LinkedHashMap<>();

    public class Element {
        public String key;
        public Object elem;

        protected Element(String string, Object arr) {
            key = string;
            elem = arr;
        }
    }

    public E get(String key, int index) {
        return arr.get(key).get(index);
    }

    // 示例:添加元素的方法需确保存入E类型
    public void addElement(String key, E element) {
        arr.computeIfAbsent(key, k -> new ArrayList<>()).add(element);
    }
}

修改后的子类 SMONArray

public class SMONArray extends SMONArr<SMONArray.Element> {

    public class Element extends SMONArr.Element {
        protected int x, y, w, h;

        protected Element(String string, Object arr) {
            super(string, arr);
        }
    }

    public Element getSelected(String key, int index) {
        return get(key, index); // 类型匹配,无需强制转换
    }
}

方案2:创建子类Element实例(不修改父类时使用)

如果无法修改父类,可在获取父类Element后,创建子类Element实例并复制属性:

public Element getSelected(String key, int index) {
    SMONArr.Element parentElement = get(key, index);
    // 初始化子类Element对象,复制父类属性
    Element childElement = new Element(parentElement.key, parentElement.elem);
    // 可在此初始化x、y、w、h等子类属性
    return childElement;
}

注意:此方法会创建新对象,而非直接转换原有实例,需根据业务场景判断是否适用。

内容的提问来源于stack exchange,提问作者Hasen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:39:27