【问题标题】:class cast exception: java.lang.String incompatible with [Ljava.lang.Object;类转换异常:java.lang.String 与 [Ljava.lang.Object; 不兼容;
【发布时间】:2011-11-17 11:06:34
【问题描述】:

下面的代码有什么问题?

List<Object[]> currencies = null;
List<String> currencyList = new ArrayList<String>();

//code to fetch currency
String currencySql = "select C.Currency from Currency C";
Query currencyQuery = this.em.createQuery(currencySql);

currencies = currencyQuery.getResultList();

for (Object[] currency : currencies) {    //getting runtime error here
   for (int i = 0; i < currency.length; i++) {
            currencyList.add(currency[i].toString());
        }
    }

在 for 循环的第一行出现运行时错误: java.lang.ClassCastException: java.lang.String 与 [Ljava.lang.Object; 不兼容;

代码编译正常。

有什么问题?

【问题讨论】:

    标签: java string list object casting


    【解决方案1】:

    我不确定您为什么认为 Query 会返回 Object 数组列表。

    查询很可能会返回Strings 的列表(除非 Currency 实体包含 Currency 对象,在这种情况下我会重新审视数据设计),因此在假设这是一个标量查询的情况下进行操作,您的代码可以简化为:

    String currencySql = "select C.Currency from Currency C";
    Query currencyQuery = this.em.createQuery(currencySql);
    
    List<String> currencyList = (List<String>) currencyQuery.getResultList();
    

    【讨论】:

    • 谢谢!!因此,如果查询是针对多列的,那么在这种情况下 getResultList 将返回 Object 数组的列表。但在这种情况下,它只有一列,即字符串,它返回一个字符串列表。正确???
    • 这取决于您的 EntityManager 的具体实现,但看起来确实如此。
    【解决方案2】:

    在调试器中检查货币变量之后的内容

    currencyQuery.getResultList();
    

    可能不是 Object[] 的列表,而是字符串的列表。

    【讨论】:

    • 将货币更改为 List 引发 java.lang.ClassCastException: java.lang.String incompatible with [Ljava.lang.String;
    • 我的意思不是 List,而是 List,因为看起来您的查询返回一列,该列被转换为字符串列表。
    【解决方案3】:

    问题是currencyList 的类型应该是List 而不是List&lt;Object[]&gt;。这也意味着循环中的currency 变量应该是Object 类型,因此它实际上与String 兼容(这就是异常的来源)。然后,您需要验证其中是否包含字符串。

    或者,您已经在 SQL 中获得了足够的信息来知道结果实际上是 List&lt;String&gt;,这反过来又允许您将 currency 声明为 String 类型。但这将涉及形式上不安全的演员表;这将是一个您知道它正确但编译器不正确的地方,因此您会收到警告。这将是抑制警告的合适位置(尽管只是在那个分配/演员中;您想尽量避免抑制警告,因为这可能会掩盖严重的问题)。

    【讨论】:

    • 而且结果绝对不是任何东西的数组列表。
    • 那么是hibernate根据返回的东西的类型从SQL中决定返回字符串列表还是对象列表???
    • 它知道类型。它知道每行中有多少个值。它说“每行一个值;行值那个值”,而不是浪费地把它放在一个长度为 1 的数组中。
    【解决方案4】:

    我认为您从查询中获取的货币列表有问题。您不需要创建另一个数组。试试这个

    List<String> currencyList = new ArrayList<String>();
    
    //code to fetch currency
    String currencySql = "select C.Currency from Currency C";
    Query currencyQuery = this.em.createQuery(currencySql);
    
    currencies = currencyQuery.getResultList();
    
    for (String currency : currencies) {    
        currencyList.add(currency);
    }
    

    【讨论】:

    • 我不确定 getResultList 返回什么。我会假设它是一个列表。还是返回对象数组?
    猜你喜欢
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多