Java泛型实现通用FileLoader时返回具体对象报错如何解决
问题修复方案
错误根因
你遇到的报错本质是泛型定义与实现逻辑不匹配,叠加类型擦除导致的类型校验失败,核心问题点如下:
TransactionConverter声明了泛型<T>,但内部硬编码返回Transaction对象,和泛型声明的返回类型T冲突- 自定义的
Converter接口没有被TransactionConverter实现,泛型约束完全失效 CSVFileLoader中定义的泛型C没有实际作用,Converter实例也没有绑定泛型,运行时类型擦除后无法匹配期望的返回类型
具体修复步骤
1. 调整Converter接口定义
扩展为支持不同源类型的通用接口,方便后续适配Excel等其他文件格式:
public interface Converter<T, S> { List<T> convert(Iterable<S> records); }
2. 修正TransactionConverter实现
删除无意义的泛型声明<T>,直接绑定返回类型为Transaction,实现Converter接口:
public class TransactionConverter implements Converter<Transaction, CSVRecord> { @Override public List<Transaction> convert(Iterable<CSVRecord> records) { List<Transaction> transactions = new ArrayList<>(); for(CSVRecord r: records){ transactions.add(convertSingle(r)); } return transactions; } private Transaction convertSingle(CSVRecord r){ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); LocalDate transactionDate = LocalDate.parse(r.get(0), formatter); String ticker = r.get(1); TransactionType transactionType = TransactionType.valueOf(r.get(2)); Double amount = Double.parseDouble(r.get(3)); Double quantity = Double.parseDouble(r.get(4)); return new Transaction(ticker, "",transactionDate, transactionType, amount, quantity); } }
3. 修正FileLoader接口与CSVFileLoader实现
删除无用泛型C,补充泛型约束:
public interface FileLoader<T> { List<T> load(); } public class CSVFileLoader<T> implements FileLoader<T> { private String filePath; private Converter<T, CSVRecord> converter; private Logger logger = LoggerFactory.getLogger(CSVFileLoader.class); public CSVFileLoader(String filePath, Converter<T, CSVRecord> converter){ this.filePath = filePath; this.converter = converter; } @Override public List<T> load() { List<T> result = null; // 改用try-with-resources自动关闭流,避免资源泄漏 try (Reader in = new FileReader(filePath)) { Iterable<CSVRecord> records = CSVFormat.RFC4180.withHeader("ID", "CustomerNo", "Name").parse(in); result = converter.convert(records); } catch (FileNotFoundException e) { logger.info("Unable to load file " + filePath); } catch (IOException e) { e.printStackTrace(); } return result; } }
4. 使用示例
Converter<Transaction, CSVRecord> transactionConverter = new TransactionConverter(); FileLoader<Transaction> loader = new CSVFileLoader<>("your_file_path.csv", transactionConverter); List<Transaction> transactions = loader.load();
扩展说明
后续需要实现ExcelFileLoader时,仅需新增对应Excel行记录的Converter实现即可,无需修改现有加载逻辑,完全符合你最初设计的通用文件加载器目标。
内容的提问来源于stack exchange,提问作者serah
相关产品推荐
相关产品推荐

