Java使用带泛型的工厂模式实现Excel导入时出现类型不匹配错误
错误原因
你当前的类型不匹配报错是因为父类Extractor中importExcel方法声明的返回值为List<?>(无界通配符列表),Java编译器在编译阶段只会校验声明的方法签名,不会识别运行时实际返回的子类MyDataExtractor的返回类型是List<MyData>,因此直接赋值会触发类型校验失败。
最优解决方案:给抽象类添加泛型约束
你可以通过给Extractor、ExtractorConfig增加泛型参数,在编译阶段就锁定返回的实体类型,从根本上解决类型安全问题:
1. 修改ExtractorConfig类,增加泛型支持
public class ExtractorConfig<T> { // 存储要转换的目标实体类型 private Class<T> type; private String fileName; private Double startRow; private Double endRow; private String sheetName; // 补充对应getter、setter public Class<T> getType() { return type; } public void setType(Class<T> type) { this.type = type; } // 其他属性的getter、setter保持原有逻辑即可 }
2. 修改抽象类Extractor,增加泛型约束
public abstract class Extractor<T> { // 方法返回值用泛型T替代通配符 public abstract List<T> importExcel(); public abstract T processRow(Row currentRow); // 工厂方法也适配泛型,类型校验通过后返回对应泛型的提取器实例 public static <T> Extractor<T> createFromConfig(ExtractorConfig<T> ec) { if (ec.getType() == MyData.class) { // 已经校验类型匹配,此处强转是安全的 return (Extractor<T>) new MyDataExtractor((ExtractorConfig<MyData>) ec); } // 后续新增其他实体的提取器,在此处补充判断分支即可 return null; } }
3. 修改MyDataExtractor指定泛型参数
// 继承父类时指定泛型为MyData public class MyDataExtractor extends Extractor<MyData> { ExtractorConfig<MyData> c; public MyDataExtractor(ExtractorConfig<MyData> c) { super(); this.c = c; } @Override public List<MyData> importExcel() { List<MyData> aList = new ArrayList<>(); // 原有导入逻辑不需要修改 return aList; } @Override public MyData processRow(Row currentRow) { MyData myDataObject = new MyData(); // 原有行处理逻辑不需要修改 return myDataObject; } }
4. 修改main方法调用代码
// 声明配置时指定泛型为MyData ExtractorConfig<MyData> ec = new ExtractorConfig<>(); ec.setType(MyData.class); ec.setFileName("MyData.xlsx"); ec.setStartRow(2d); ec.setEndRow(3241d); ec.setSheetName("Sheet1"); // 获取到的提取器已经带MyData泛型约束 Extractor<MyData> e = Extractor.createFromConfig(ec); List<MyData> myDataList = e.importExcel();
临时解决方案(不推荐)
如果不想改动现有框架结构,也可以通过双层强转绕过编译校验,缺点是没有编译期类型校验,类型不匹配时会在运行时报错:
List<MyData> myDataList = (List<MyData>)(List<?>) e.importExcel();
内容的提问来源于stack exchange,提问作者user3762790
相关产品推荐
相关产品推荐

