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
相关产品推荐
相关产品推荐

