类型安全性:取消选中从对象转换为列表 [英] Type safety: Unchecked cast from Object to List
问题描述
SqlOutParameter out = new SqlOutParameter(out_refcursor,OracleTypes.CURSOR,new StudentRowMapper());
//一些代码..
MapSqlParameterSource参数= createMapSqlParameterSource();
parameters.addValue(in_studentid,101);
地图< String,Object> result = simpleJdbcCall.execute(参数);
列表< Student> students =(List< Student>)result.get(out_refcursor); //这里我得到一个警告
定义 execute()
方法:
Map< String,Object> org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SqlParameterSource parameterSource)
执行存储过程并返回一个输出参数的映射,按照参数声明中的名称进行键控。
上述行中的警告: List< Student> ; students =(List< Student>)result.get(out_refcursor);
是类型安全:未检查从对象转换为列表
我知道这只是一个编译时间警告,而Offcourse我可以做一个 @SuppressWarnings(unchecked)
来压制它。
问题:但我该如何正确施放它?
-
我试过的一种方法是:
$ b $ p $列表与LT;学生> students = castObject(result.get(out_refcursor));
@SuppressWarnings(unchecked )
private static< T extends List<?>> T castObject(Object obj){
return(T)obj;
}
在castObject()方法中放入 @SuppressWarnings(unchecked)
。我不知道这是否是正确的做法。
列表<?> students = castObject(result.get(out_refcursor));
Student student =(Student )students.get(0);
private static< T extends List<?>>列表与LT;?> castObject(Object obj){
if(obj instanceof List<?>){
return(List< Student>)obj;
}
返回null;
}
任何建议/建议受欢迎的。
您的第二个解决方案将无济于事(由于 Type Erasure ),并且会导致其他问题,所以这可能不是一个好主意。
第一种方法可能在实践中有效,但确实有点不妥。 Java中的子类化和子类化参数存在细微差别(但巨大的差异) - 即 ArrayList< Integer>
不是 ArrayList< Object>
的子类,但是 ArrayList< String>
是子类型集合< String>
:参见一个更有趣的示例。 维基百科关于协变的条目中更正式的计算机科学背景。
因此,IMO应该保留在那里投射,保留(必要的)注释并捕获 ClassCastException
以确保包括例外(因此名称)的情况。
SqlOutParameter out = new SqlOutParameter("out_refcursor",OracleTypes.CURSOR,new StudentRowMapper());
// some code..
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
Definition of execute()
method:
Map<String, Object> org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SqlParameterSource parameterSource)
"Execute the stored procedure and return a map of output params, keyed by name as in parameter declarations.."
The warning on the above line : List<Student> students = (List<Student>) result.get("out_refcursor");
is "Type safety: Unchecked cast from Object to List"
I understand it is only a compile time warning, and Offcourse I can do a @SuppressWarnings("unchecked")
to supress it.
Question: But how do I properly cast it?
One way I tried out is
List<Student> students = castObject( result.get("out_refcursor"));
@SuppressWarnings("unchecked") private static <T extends List<?>> T castObject(Object obj){ return (T)obj; }
Still I had to put @SuppressWarnings("unchecked")
in the castObject() method. And I don't know if this is correct way of doing.
Second way I tried is,
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; }
Any suggestions/advice are welcome.
Your second solution won't help (due to Type Erasure), and will cause other problems too so probably not a good idea.
The first method will probably work in practice, but is a bit dodgy really. There's a subtle (but huge) difference between sub-classing Generic types and subclassing their parameters in Java - i.e. ArrayList<Integer>
is not a subclass of ArrayList<Object>
, but ArrayList<String>
is a sub-type of Collection<String>
: see a more fun example. More formal Computer Sciencey background in Wikipedia entry on Covariance.
So, IMO you should keep the casting there, keep the (necessary) annotation, and catch the ClassCastException
to make sure that the exceptional (hence the name) cases are covered.
这篇关于类型安全性:取消选中从对象转换为列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!