Reputation: 625
Following code retrieves the value of a field using the Reflection API. As you can see in the provided image, this generates an unchecked cast warning. The warning can be suppressed using @SuppressWarnings("unchecked"). I was wondering if there is an alternative to this though?
Update: KeyType is a generic. So KeyType.class.cast(object); wouldn't work due to type erasure.
private K getId(Field idField, V o) {
K id = null;
try {
idField.setAccessible(true);
id = (K) idField.get(o);
} catch (IllegalAccessException ignored) {
/* This never occurs since we have set the field accessible */
}
return id;
}
Solution: Seems like the SuppressWarnings annotation IS the way to go here.. thanks for your time guys.
Upvotes: 3
Views: 3747
Reputation: 31300
The Class method cast doesn't require the @SupressWarnigns even though it still can throw ClassCastException.
KeyType keyType = KeyType.class.cast( idField.get(o) );
You can - since at that location you should know the generic paramter(s) - proceed like this:
private static class ListInteger extends ArrayList<Integer>{}
Object obj = new ArrayList<Integer>();
ListInteger test = ListInteger.class.cast(obj);
Once you have an object of class KeyType you can, of course,
KeyType keyTypeX = ...; // not null
KeyType keyType = keyTypeX.getClass().cast( obj );
There are alternatives, although the @SuppressWarnings isn't so bad - try to limit it to an declaration+assignment, don't put it on the method.
Upvotes: 2
Reputation: 6414
The signature of get
method of Field is
public Object get(Object obj) {
...
}
Since it is not generic, the return type is Object, you cannot enforce any error to appear at compile-time.
If you are sure that the type of the value is ValueType
all the time, then add documentation to the method, saying the type will be always ValueType and use @SuppressWarnings("unchecked").
Upvotes: 1