SqlOutParameter out = new SqlOutParameter("out_refcursor",OracleTypes.CURSOR,new StudentRowMapper());
//一些代码..
MapSqlParameterSource parameters = createMapSqlParameterSource();
parameters.addValue("in_studentid","101");
Map<String, Object> result = simpleJdbcCall.execute(parameters);
List<Student> students = (List<Student>) result.get("out_refcursor"); // here I get a warning
execute()
方法的定义:
Map<String, Object> org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SqlParameterSource parameterSource)
&#34;执行存储过程并返回输出参数的映射,按名称键入,如参数声明中所示。&#34;
以上行警告:List<Student> students = (List<Student>) result.get("out_refcursor");
是&#34;类型安全:未选中从对象转换为列表&#34;
我知道这只是一个编译时警告,而且我可以做一个@SuppressWarnings("unchecked")
来压制它。
问题:但我该如何正确施展呢?
我试过的一种方法是
List<Student> students = castObject( result.get("out_refcursor"));
@SuppressWarnings("unchecked")
private static <T extends List<?>> T castObject(Object obj){
return (T)obj;
}
仍然我必须将@SuppressWarnings("unchecked")
放在castObject()方法中。而且我不知道这是否是正确的做法。
我试过的第二种方式是,
List<?> students = castObject( result.get("out_refcursor"));
Student student = (Student)students.get(0);
private static <T extends List<?>> List<?> castObject(Object obj){
if(obj instanceof List<?>) {
return (List<Student>)obj;
}
return null;
}
欢迎任何建议/意见。
答案 0 :(得分:5)
只要您知道List
元素的类名,就可以使用这样的东西。这里有一个问题,硬编码ArrayList
实例化。
public static <T> List<T> castList(Object obj, Class<T> clazz)
{
List<T> result = new ArrayList<T>();
if(obj instanceof List<?>)
{
for (Object o : (List<?>) obj)
{
result.add(clazz.cast(o));
}
return result;
}
return null;
}
用法:
List<Student> students = castList(result.get("out_refcursor"), Student.class);
答案 1 :(得分:4)
你的第二个解决方案无济于事(由于Type Erasure),并且会引起其他问题,所以可能不是一个好主意。
第一种方法可能会在实践中起作用,但实际上有点狡猾。 子类化通用类型和在Java中对它们的参数进行子类化之间存在微妙(但巨大)差异 - 即ArrayList<Integer>
不是ArrayList<Object>
的子类},但ArrayList<String>
是Collection<String>
的子类型:请参阅a more fun example。 Wikipedia entry on Covariance中更正式的计算机科学背景。
所以,IMO你应该保持那里的转换,保留(必要的)注释,并抓住ClassCastException
以确保覆盖异常(因此名称)案例。