I have a parametrized value, that is resolved at runtime:
public class GenericsMain {
public static void main(String... args) {
final String tag = "INT";
Field field = resolve(tag);
if (tag.equals("INT")) {
/*
In here I am using the "secret knowledge" that if tag equals INT, then
field could be casted to Field<Integer>. But at the same time I see an unchecked cast
warning at here.
Is there a way to refactor the code to be warning-free?
*/
Field<Integer> integerField = (Field<Integer>) field;
foo(integerField);
}
}
public static Field resolve(String tag) {
switch (tag) {
case "INT":
return new Field<>(1);
case "DOUBLE":
return new Field<>(1.0d);
default:
return null;
}
}
public static <T> void foo(Field<T> param) {
System.out.println(param.value);
}
static class Field<T> {
public final T value;
public Field(T value) {
this.value = value;
}
}
}
Is there a way to avoid unchecked cast in the code above (marked with a long comment)?
All the answers are fine, but I think there is not enough emphasis on why you're getting a warning and are casting.
You are explicitly circumventing the type system by performing an unchecked cast. By saying "I have information about this type that is not available to the compiler" - you are telling the compiler you know better.
That is of course a possible and reasonable use case: otherwise these casts would not be allowed, but a warning is good since it indicates you should be really sure what the type is.
This makes perfect sense. In fact, if you check libraries like GSON that do serialization they are full of these warnings and supressions.
Don't worry about your code - it's all fine. If there was a way to "trick" the compiler to not emit the warning that would have been a serious problem on the other hand :)
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