ArrayList首元素为String[][]时类型转换出现ClassCastException问题求助
看起来你在这里踩了Arrays.asList的一个小坑,我来帮你理清楚问题出在哪,以及怎么解决。
首先,先揪出错误的根源:你的ArrayList第一个元素是String[][](二维字符串数组),但你用Arrays.asList(o)处理它时,这个方法会把整个二维数组当成List的单个元素,而不是把二维数组里的每一行(一维数组)拆成List的元素。所以当你调用l.get(tokenInd)时,拿到的其实是整个String[][]对象,这时候你试图把它强转成String[]或者ArrayList,自然就会抛出ClassCastException——毕竟二维数组和一维数组完全是不同的类型嘛。
正确的处理方式
你不需要用Arrays.asList来包装第一个元素,直接把它强转成String[][]就可以了,之后再按需处理里面的一维数组:
// 假设results是你的ArrayList<Object> ArrayList<Object> results = ...; // 先处理第一个元素:String[][] if (!results.isEmpty()) { Object firstItem = results.get(0); // 先做类型检查,避免直接强转出错 if (firstItem instanceof String[][]) { String[][] twoDArray = (String[][]) firstItem; // 如果要获取某一行的长度,直接通过数组索引访问 int tokenInd = ...; // 你的行索引 if (tokenInd >= 0 && tokenInd < twoDArray.length) { int len = twoDArray[tokenInd].length; // 这里就可以正常使用len了 } // 如果你确实需要把二维数组转成List<String[]>,可以这样做 List<String[]> rowList = Arrays.asList(twoDArray); String[] targetRow = rowList.get(tokenInd); int len = targetRow.length; } } // 再处理剩下的ArrayList元素 for (int i = 1; i < results.size(); i++) { Object item = results.get(i); if (item instanceof ArrayList<?>) { ArrayList<?> listItem = (ArrayList<?>) item; int size = listItem.size(); // 处理这个ArrayList的逻辑 } }
为什么原来的代码会报错?
再仔细说下Arrays.asList(o)的行为:当你传入的参数是一个对象数组时,Arrays.asList会把数组里的每个元素作为List的元素;但如果传入的是一个二维数组(比如String[][]),它本质上是一个“元素为一维数组的数组”,而Java会把整个二维数组当成一个单独的对象传入可变参数列表,所以最终得到的List里只有一个元素——就是这个二维数组本身。
举个直观的例子:
String[][] arr = {{"a", "b"}, {"c", "d"}}; List<?> list = Arrays.asList(arr); // list.size() 是1,list.get(0)就是整个arr对象
这就是为什么你调用l.get(tokenInd)拿到的是String[][],强转成String[]必然失败。
额外建议
在处理这种混合类型的ArrayList时,尽量先做instanceof类型检查,这样可以避免因为类型不匹配导致的运行时异常,让代码更健壮。
内容的提问来源于stack exchange,提问作者cp.

