Why do I get an unchecked cast warning on this generic type?

Go To StackoverFlow.com

1

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?

2012-04-04 22:09
by sangfroid


4

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.

2012-04-04 22:13
by Jeffrey
Good call! And thanks for the speedy response. Haven't used Class.cast before, but I think I like it - sangfroid 2012-04-04 22:28
@PaulBellora I don't use hadoop, but the reference I found showed Writable - Jeffrey 2012-04-05 01:25
@Jeffrey - My mistake! I skimmed too quickly and assumed the OP was using Class#newInstance, completely missing the hadoop part - Paul Bellora 2012-04-05 01:28


3

All T's are Writable, but not all Writables are Ts. 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.

2012-04-04 22:12
by Louis Wasserman
You copied my answer ; - ControlAltDel 2012-04-04 22:13
Nope, StackOverflow says mine was posted at 22:12:14, but yours was posted 30 seconds later at 22:12:44. It's the other way around. ; - Louis Wasserman 2012-04-04 22:13
Yes but I know for sure that I THOUGHT it first :- - ControlAltDel 2012-04-04 22:15


1

All T's are Writable, but not all Writables are T's

2012-04-04 22:12
by ControlAltDel
Ads