sangfroid
sangfroid

Reputation: 3803

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

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

Answers (3)

Jeffrey
Jeffrey

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

ControlAltDel
ControlAltDel

Reputation: 35011

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

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198014

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.

Upvotes: 3

Related Questions