Reputation: 3803
So here's my code :
public class SetWritable<T extends Writable> implements Writable {
private Class<? extends Writable> valueClass;
private Set<T> values;
public SetWritable(Class<T> valueClass) {
this.valueClass = valueClass;
this.values = new HashSet<T>();
}
public void readFields(DataInput in) throws IOException {
values = new HashSet<T>();
int len = in.readInt();
for (int i = 0; i < len; i++) {
//this line is where I get the warning
//FYI, WritableFactories.newInstance returns an instance of Writable
T value = (T) WritableFactories.newInstance(valueClass);
value.readFields(in);
values.add(value);
}
}
}
What's confusing to me is this : I've asserted that T extends Writable, so why am I getting a warning when I try to cast the Writable to T? And since I know T extends Writable, is it safe to suppress this warning?
Upvotes: 1
Views: 181
Reputation: 44798
You are getting the warning because WritableFactories.newInstance
returns a Writable
and your T
extends Writable
, so it might not be a safe cast. However, since you are using Class<T>
as your argument to newInstance
it is safe to suppress this warning.
It might be better to store valueClass
as Class<T>
and use Class#cast
to cast for you, then you won't have any ugly @SuppressWarnings
hanging over your method.
Upvotes: 4
Reputation: 198014
All T
's are Writable
, but not all Writable
s are T
s. So when you cast a Writable
to T
, it can't be sure that the Writable
is actually a T
.
For example, imagine there was an S extends Writable
. The newInstance
might be an S
and not a T
, but it'd still be Writable
-- but casting it to T
would give you a ClassCastException
.
Upvotes: 3