2

I have the below code which casts a List object type, and I want to avoid using the @SuppressWarnings("unchecked") annotation, but I do not want to turn it off in IDE settings as I realise the importance of it.

How would I rewrite the below so I can remove the annotation and the IDE doesnt highlight an unchecked cast warning?

I tried replacing the CaseData with a ? element type, but I need to state CaseData for code later in the class.

I've looked at popular questions such as this: What is SuppressWarnings ("unchecked") in Java?

@Override
protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request,
        HttpServletResponse response) throws Exception {

@SuppressWarnings("unchecked")
    List<CaseData> cases = (List<CaseData>) model.get("cases");
Lii
  • 11,553
  • 8
  • 64
  • 88
Coder
  • 197
  • 1
  • 17

3 Answers3

2

There is no way to do exactly this without a warning. A cast to a generic type simply cannot be check during runtime, and the compiler will inform you about that. I think that it is often totally legitimate to suppress that warning, so I don't think you really need another solution.

But if you can, follow @KarolDowbecki's suggestion, I think that is the best solution.

If you want to avoid SuppressWarning anyway, the following are some work-arounds:

Perform the cast when when you are using the CaseData elements, instead of casting the whole list:

List<?> cases = (List<?>) model.get("cases");

// No warning here, since we're casting the element instead of the list
CaseData data = (CaseData) cases.get(0);

Copy the cases list and check all elements before hand:

// No warning here, since we're casting to List<?>
List<CaseData> cases = ((List<?>) model.get("cases")).stream()
// No warning here, since we're casting the elements instead of the list
    .map(d -> (CaseData) d).collect(toList());
Lii
  • 11,553
  • 8
  • 64
  • 88
  • Thanks for the response. Would need to add the cast to your first suggestion: List> cases = (List>) model.get("cases"); I'll try these out – Coder Dec 03 '19 at 10:01
  • @Coder: Oh, I missed a cast there, sorry. Fixed. – Lii Dec 03 '19 at 11:23
1

If Map<String, Object> contains mixed value types e.g. cases => List<CaseData> but users => Set<User> than you would have to replace the Map<String, Object> with a custom data class that will maintain the types:

class Model {
  List<CaseData> cases;
  Set<User> users;
}

and use it in the method signature:

void buildExcelDocument(Model model, ...) {
  List<CaseData> cases = model.getCases();
}
Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
0

If you do not want to change your map as suggested by Karol, you could circumvent the issue by casting later and doing a proper check then:

List<?> cases = model.get("cases");

//later in the code...

if(cases.get(0) instanceof CaseData){
   CaseData case1 = (CaseData) cases.get(0);

   //do stuff
}
SteffenJacobs
  • 402
  • 2
  • 10