Warning: [unchecked] unchecked conversion
Answer 1:
List<Question> qList = (List<Question>) session.getAttribute("qList");
Answer 2:
List<ExamSchedule> eList = new ArrayList<ExamSchedule>();
Grasp first the idea of Generics.
As for the first answer, if you're using HttpSession
, there is no chance of calming the warnings without annotating your statement with @SuppressWarnings
like so:
@SuppressWarnings("unchecked")
List<Question> qList = (List<Question>) session.getAttribute("qList");
This is due to the Servlet API which returns an Object
from HttpSession.getAttribute()
. The compiler will warn you of type-safety (unchecked cast from Object
to List<Question>
) otherwise.
List<Question> qList = (List) session.getAttribute("qList");
session.getAttribute("qList");
will return instance of typeObject
. So you need to explicitly cast it.(List)
is just raw type,List<String>
is generic type , so trying to cast raw type to generic type reference gives a warning.
Now, if you do this:
List<Question> qList = (List<Question>) session.getAttribute("qList");
The cast is a runtime check but there will be a type erasure at runtime, so there's actually no difference between a List<String>
and List<Foo>
etc.Hence you get that error.
So try (List<?> list)
This type conversion verifies that the object is a List
without caring about the types held within.
List<ExamSchedule> eList = new <ExamSchedule>ArrayList();
That is a syntax error.It should be ArrayList<ExamSchedule>
, not <ExamSchedule>ArrayList
.
Suggestions :
List<?> qList = (List<?>) session.getAttribute("qList");
List<ExamSchedule> eList = new ArrayList<ExamSchedule>();
Java doesn't have reified generics; the list doesn't carry its elements' type at runtime. So, an attempt to cast to a bounded type will give you a warning; you might think you know the type, but the compiler reminds you that might be wrong.
You can cast to an unbound collection, then check the type of each individual element.
List<?> tmp = (List<?>) session.getAttribute("qList");
if (tmp != null) {
for (Object o : tmp) {
Question q = (Question) o;
/* Use q ... */
}
}
If you need a List<Question>
to pass to some API, you can copy the elements to a new, correctly declared list inside the loop. Obviously, this is a lot of clutter that you should factor into a utility method. But to make it flexible, you'd probably want to use dynamic type casts.
public static <T> List<T> asList(Collection<?> c, Class<? extends T> type) {
if (c == null)
return null;
List<T> list = new ArrayList(c.size());
for (Object o : c)
list.add(type.cast(o));
return list;
}
List<Question> qList = asList((Collection<?>) session.getAttribute("qList"), Question.class);
There are methods in java.util.Collections
that do almost what you need; unfortunately, they don't check the type of elements in the original wrapped collection. Also, since they wrap the underlying collection instead of creating a new, independent collection, they could still create type errors.
Luckily, the second question is easy:
List<ExamSchedule> eList = new ArrayList<>();