java.lang.Integer无法强制转换为java.lang.String错误解决
问题描述
遇到错误:java.lang.Integer cannot be cast to java.lang.String,错误触发点为代码中的循环段(代码内已标注)。尝试使用Integer.parseInt(string)方法修复,但问题仍存在。相关代码如下:
private List<Integer> getMediasToDelete() { try (Table table = TableFileFactory.fromFile(excelFilePath, 0)) { Iterator<TableRow> rows = table.rowsIterator(); List<String> definitiveMediaToDeleteList; String mediaToKeep; while (rows.hasNext()) { TableRow row = rows.next(); definitiveMediaToDeleteList = row.getCellValueAsList("A", ","); mediaToKeep = row.getCellValue("B", ","); definitiveMediaToDeleteList.remove(mediaToKeep); mediasIdsToDelete.addAll(definitiveMediaToDeleteList); List<String> folderIdOfMedia = getService(TransactionService.class).withReadOnlyTransaction(this::getFolderId); // 错误触发的循环段 for (String folderId : folderIdOfMedia) { App.getService(FolderService.class).addMedia(Integer.parseInt(folderId), Integer.parseInt(mediaToKeep)); } mediaIdDominantByMediaIdToDelete.put(Integer.parseInt(mediaToKeep), definitiveMediaToDeleteList.stream().map(Integer::parseInt).collect(Collectors.toList())); } return mediasIdsToDelete.stream().map(Integer::parseInt).collect(Collectors.toList()); } catch (Exception e) { REPORT.error("Error, cannot retrieve the medias ids", e); return null; } } private List<String> getFolderId() { final String mediasQueryAsString = "SELECT folder_id" + " FROM media_in_folder" + " WHERE media_id in ( :mediasIdToDelete )"; final Query mediaQuery = App.getCurrentSession().createSQLQuery(mediasQueryAsString); mediaQuery.setParameterList("mediasIdToDelete", mediasIdsToDelete); final List<String> folderIdList = QueryHelper.list(mediaQuery); if (CollectionUtils.isEmpty(folderIdList)) { return Collections.emptyList(); } return folderIdList; } public static List list(final Query q) { return get().processQuery(q, () -> q.list()); }
错误根源
- 类型声明与实际返回值不匹配:
getFolderId()方法声明返回List<String>,但数据库中folder_id是数值类型,Hibernate执行原生SQL查询后,会将结果封装为Integer对象存入列表。将这个List<Integer>强行赋值给List<String>,会导致后续遍历folderIdOfMedia时,JVM尝试把Integer对象强转为String,直接触发ClassCastException。 Integer.parseInt未生效的原因:错误发生在for (String folderId : folderIdOfMedia)这一步,根本到不了Integer.parseInt(folderId)的执行环节——遍历过程中的类型转换已经失败了。
修复方案
方案1:修正返回类型,直接使用数值类型
这是最直接的修复方式,避免不必要的类型转换:
- 修改
getFolderId()的返回类型为List<Integer>:
private List<Integer> getFolderId() { final String mediasQueryAsString = "SELECT folder_id" + " FROM media_in_folder" + " WHERE media_id in ( :mediasIdToDelete )"; final Query mediaQuery = App.getCurrentSession().createSQLQuery(mediasQueryAsString); mediaQuery.setParameterList("mediasIdToDelete", mediasIdsToDelete); final List<Integer> folderIdList = QueryHelper.list(mediaQuery); if (CollectionUtils.isEmpty(folderIdList)) { return Collections.emptyList(); } return folderIdList; }
- 对应修改循环段代码,无需再调用
Integer.parseInt:
for (Integer folderId : folderIdOfMedia) { App.getService(FolderService.class).addMedia(folderId, Integer.parseInt(mediaToKeep)); }
方案2:SQL查询时强制转换为字符串
如果业务逻辑要求必须返回List<String>,可以在SQL中将folder_id转换为字符串类型,确保查询结果是字符串:
final String mediasQueryAsString = "SELECT CAST(folder_id AS CHAR)" + " FROM media_in_folder" + " WHERE media_id in ( :mediasIdToDelete )";
此时QueryHelper.list()返回的是String类型列表,后续的Integer.parseInt(folderId)可以正常执行,不会触发类型转换异常。
额外建议
- 检查
mediasIdsToDelete的泛型类型:从代码逻辑看,它接收的是List<String>,但作为SQL查询参数时,确保Hibernate能正确处理字符串类型的ID参数。 - 优化异常捕获:开发阶段可以针对性捕获
ClassCastException并打印详细堆栈,或者避免捕获所有Exception,便于快速定位问题。
内容的提问来源于stack exchange,提问作者JhinKazama
相关产品推荐
相关产品推荐

