I have researched this extensively and cant seem to find a best practice for this scenario.
ArrayList<GenericObject<?>> list = new ArrayList<>();
list.add( new GenericObject<Integer>(6) ); // Autoboxing
list.add( new GenericObject<String>("HI") );
if(list.get( 0 ).getGenaricValue().getClass() == Integer.class){
GenericObject<Integer> gi = (GenericObject<Integer>) list.get( 0 );
System.out.println("Was Integer");
System.out.println(gi);
}
}
while this block of code works the cast from GenericObject <?> to GenericObject<Integer> gives an unchecked warning. Now as you can see i have clearly checked the type with my if statement so I am not paranoid about an exception but is there a better way to do this without having to suppress the unchecked warning? Is there a best practice for this scenario? I have read the entire Generics oracle tutorial here and i have read a lot of stackoverflow posts but none that seem to answer this problem. any help would be appreciated thanks.
In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).
To declare an upper-bounded wildcard, use the wildcard character ('? '), followed by the extends keyword, followed by its upper bound. Implementation: Java.
Guidelines for Wildcards. Upper bound wildcard − If a variable is of in category, use extends keyword with wildcard. Lower bound wildcard − If a variable is of out category, use super keyword with wildcard. Unbounded wildcard − If a variable can be accessed using Object class method then use an unbound wildcard.
No, there's no better way than to suppress the warning, with an explanation:
@SuppressWarnings("unchecked") // this is okay because [insert reasoning]
GenericObject<Integer> gi = (GenericObject<Integer>) list.get( 0 );
Note that this isn't necessarily a good design however - it's best to avoid unchecked casts if possible, if only because they can be hard to justify. For example, what if gi
had earlier been typed as a GenericObject<Object>
or GenericObject<Number>
and just happened to hold an Integer
? It might be better to check and cast the value itself:
GenericObject<?> go = list.get(0);
Object obj = go.getGenericValue();
if (obj instanceof Integer) { // or obj.getClass() == Integer.class
System.out.println("Was Integer");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With