我有一种从数据库获取联系人列表的方法。它返回一个List
public List<String[]> getContacts(String param) {
...
Query q = this.getCurrentSession().createSQLQuery("
select first_name, last_Name, email_address, fax
from contacts
where first_name = :param");
q.setParameter("param", param);
List<String[]> listResult = q.list();
return listResult;
}
当我使用以下代码获取联系人姓名时:
List<String[]> contacts = (ArrayList<String[]>) contactManager.getContacts(fistName);
if (contacts != null && contacts.size() > 0) {
person.setLastName(contacts.get(0)[1]); //error line
}
我收到错误:
java.lang.ClassCastException:[Ljava.lang.Object;无法施展 [Ljava.lang.String;
我将源代码更改为:
List<String[]> contacts = (ArrayList<String[]>) contactManager.getContacts(fistName);
if (contacts != null && contacts.size() > 0) {
Object[] objTemp = contacts.get(0);
String temp = (String) objTemp[1];
person.setLastName(temp);
}
运行良好!
我已经调试过,getContacts()函数返回的对象仍然是List。看起来像对象刚刚转换为List,错误行运行。
请帮我解释为什么第二个代码可以正常运行。我认为2个来源是相同的逻辑。
答案 0 :(得分:3)
在这里你试着明确地施放:
List<String[]> contacts = (ArrayList<String[]>) contactManager.getContacts(fistName)
但执行此操作时:
contacts.get(0)[1]
它首先将数组的运行时类型(Object [])转换为String [],如:
Object[] colors = { "red", "green", "blue" };
String[] colorsStrings = (String[]) colors; // -> class cast exception
你得到:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
正确地告诉您正在尝试将Object
s(Object[].class
)数组转换为String
s(String[].class
)数组。
因此,您需要首先从列表中显式获取Object [],然后将单个项目从Object转换为String,如上例所示。
如果您使用Java 8,另一个选择是:
String[] contacts = Arrays.stream(contactManager.getContacts(fistName))
.toArray(String[]::new);
答案 1 :(得分:1)
问题是您没有遵循警告。一切都从这里开始:
public List<String[]> getContacts(String param) {
Query q = this.getCurrentSession().createSQLQuery("select first_name, last_Name, email_address, fax from contacts where first_name = :param");
q.setParameter("param", param);
List<String[]> listResult = q.list();
return listResult;
}
List<String[]> listResult = q.list();
这应该会给你一个警告
The expression of type List needs unchecked conversion to conform to List<String[]>
我们可以用一些示例代码替换它在底层运行的内容。
public List getContacts(String param){
Object[] data = new Object[3];
data[0] = "String";
List result = new ArrayList<>();
result.add(data);
return result;
}
如您所见,hibernate创建一个没有定义类型的列表,并将一个Object []数组放入其中。
在编译期间,Java会删除所有通用参数,您的代码看起来更像这样。
public List<Object[]> getContacts(String param) {
Query q = this.getCurrentSession().createSQLQuery("select first_name, last_Name, email_address, fax from contacts where first_name = :param");
q.setParameter("param", param);
List<Object[]> listResult = q.list();
return listResult;
}
和
List<Object[]> contacts = (ArrayList<Object[]>) contactManager.getContacts(fistName); //Note this cast is not required
if (contacts != null && contacts.size() > 0) {
person.setLastName(contacts.get(0)[1]); //error line
}
因此,您将Object传递给期望String的方法。这就是为什么当你打开它并手动投射它的工作原理。
使用Dileep建议的解决方案
List<String> listResult = q.setParameter("param", param).setResultTransformer(Transformers.aliasToBean(String.class)).list();