java.lang.String无法转换为[Ljava.lang.String;。

20

我有以下内容并且出现了以下错误:

java.lang.String无法转换为[Ljava.lang.String;

我将Object[]更改为String[],因为我遇到了下一个错误:

java.lang.Object无法转换为[Ljava.lang.String;

有什么想法吗?

private Collection queryStatement(String SelectStatement) {

    int colcount = 0;
    int rowcount = 0;
    int rowcounter = 0;

    ArrayList a = new ArrayList();

    Query query = getEntityManager().createNativeQuery(SelectStatement);

    List<String[]> resultList = (List<String[]>) query.getResultList();

    if (!resultList.equals(Collections.emptyList())) {
        rowcount = resultList.size();
    }

    if (rowcount > 0) {
        colcount = ((String[]) query.getResultList().get(0)).length;
    }

    rows = rowcount;
    cols = colcount;

    String[][] array = new String[rowcount][colcount];

    for (String[] obj : resultList) {
        String[] record = new String[colcount];
        for (int colCounter = 0; colCounter < colcount; colCounter++) {
            record[colCounter] = safeValue(obj[colCounter]+"");
        }

        array[ rowcounter++] = (String[]) record;
    }
    a.add(array);
    return a;
}

你的选择语句是什么?你会写查询吗? - Nimesh
1
为什么会返回一个 List<String[]>?看起来应该返回一个 List<String>,因此出现了错误。 - Jorn Vernee
是的,它将返回List<String>,因为在查询中只有一个PASSWD列。 - Nimesh
因为查询参数(SelectStatement)可以返回List(String[])。 - Giorgos
你的代码“假设”你会得到一个List<String[]>而不是将其视为可能性之一。 - Marko Topolnik
显示剩余2条评论
4个回答

22

java.lang.String无法强制转换为[Ljava.lang.String;

当你试图将一个String类型转换为String数组时,会出现这个错误。

例如:

List list = new ArrayList<>();
list.add("foo");
String[] values = (String[])list.get(0); -> throws the exception

出现该错误的原因是query.getResultList()返回了一个List<String>List<Object>,而不是List<String[]>,所以在尝试将值转换为String[]时会出现此异常。


根据Javadoc createNativeQuery(String) 的说明,如果在select列表中只有一列,则返回类型为ObjectObject[]

方法 #1

解决该问题的一种简单方法是,可以依赖于结果的原始类型(这并不是最优雅的方法,但是最简单的方法),然后稍后您可以检查列表内容的类型来正确地进行转换。

List result = query.getResultList();

然后,您可以按如下方式检查类型:

if (resultList.isEmpty() || resultList.get(0) instanceof Object[]) {
    // Several columns in the result
    List<Object[]> resultList = (List<Object[]>) result;
    // The rest of your current code here
} else {
    // Only one column in the result
    List<Object> resultList = (List<Object>) result;
    ...
}

方法 #2

更加优雅的方式可以是创建一个 Entity 类,并使用 createNativeQuery(String sqlString, Class entityClass) 方法创建你的查询,这样它将自动将你的列与 Entity 的字段进行映射。

下面是示例代码:

private Collection<T> queryStatement(String SelectStatement, Class<T> resultType) {
    ...
    Query query = getEntityManager().createNativeQuery(SelectStatement, resultType);
    List<T> resultList = (List<T>) query.getResultList();
    ...
}

Nicolas Filotto,你是对的,但选择查询是参数,因此有时返回List<String>,如果SELECT有一列,则返回List<String[][]>,如果有多个列,则返回。有什么想法如何解决这个问题吗? - Giorgos
@NicolasFilotto,你提到的第二个语句“这个错误发生在……”并不完全正确。我认为你想说:“当你尝试将String对象强制转换为一个字符串对象数组String[]时,会发生此错误。” 如果你像你所说的那样使用单词“List”,那么你隐含地意味着java.util.List - Steve C
1
对于第二种方法,POJO需要是实体类,否则会遇到MappingException异常。对于不返回映射表或视图的本地查询,您需要选择第一种方法。 - Tobi Nonymous

1
在您的代码中,某个位置试图将String强制转换为String[]。您的堆栈跟踪将告诉您确切的位置。
除此之外,您的代码还有很多其他问题。

1
像这样做:
List<String> resultList = (List<String>) query.getResultList();
if (!resultList.equals(Collections.emptyList())) {
    rowcount = resultList.size();
}

if (rowcount > 0) {
     colcount = resultList.get(0).length;
}

请查看我在Nicolas Filotto的评论,你是正确的,但是Select查询是参数化的,因此有时会返回List<String>,如果SELECT有一列,则返回List<String[]>。 - Giorgos
你是对的@nicolas,但他在这里提到了他的查询。我已经问过他查询是什么,它只包含一个选择列。 - Nimesh

0

这行代码

ArrayList a = new ArrayList();

是一个原始类型,因此(潜在地)代码中的所有对象都可以被视为Object

尝试一下

ArrayList<String[][]> a = new ArrayList<>();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接