Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With Java, is it acceptable to use an unbounded wildcard type as a method's argument, and then check and cast it to a parameterized type?

Tags:

java

generics

If I use unbounded wildcard types for two collections (each collection will have a different type) as the arguments for a method:

private void doAssertion(List<?> testList, List<?> generatedList)

Inside this method, can I first check the type of objects in these collections, and then cast the collection to a parameterized type? This just smells bad, and I get an unchecked cast warning.

if (testList.get(0) instanceof X) {
  List<X> xList = (List<X>) testList;
  // call methods specific to X for each object
}

else if (testList.get(0) instanceof Y){
  List<Y> yList = (List<Y>) testList;
  // call methods specific to Y for each object
}

Part of my problem is that I don't have the ability to touch the code that defines classes X or Y. Otherwise, I know I can have them implement a common interface, and use a bounded type parameter. I can't overload assertEqual because both methods have the same erasure.

In my case, X and Y are always going to be children of other classes, and I'm not modifying the objects in anyway, just calling the get() methods of the objects.

like image 453
TheAmpersand Avatar asked Feb 27 '23 00:02

TheAmpersand


1 Answers

No, you shouldn't do this. Take for example:

List<Integer> myIntList = ...;
if (myIntList.get(0) instanceof Number) {
    List<Number> myNumberList = (List<Number>)myIntList;
    myNumberList.put(Double.valueOf(100)); // BAD!
}

Generic arguments are not necessarily substitutable in sub/superclass hierarchies.

like image 153
Steven Schlansker Avatar answered Apr 07 '23 23:04

Steven Schlansker