mercredi 8 juin 2016

Generics and cast

I try to write a class that take a parameter name and can return the corresponding parameter of a given object. Currently, my class look like this :

public class ParamValue<T> {

    private String paramName;

    @SuppressWarnings("unchecked")
    public T getValue(Object obj) throws Exception {

        Class<?> c = obj.getClass();
        Field param = c.getDeclaredField(paramName);
        boolean isAccessible = param.isAccessible();
        param.setAccessible(true);
        Object value = param.get(obj);
        param.setAccessible(isAccessible);
        return (T) value;
    }

    // get set ...
}

Now, imagine that we have an object with a simple Long parameter :

public class ExampleClass {

    private Long value;

    // get set ...
}

We can do this to get back the long value :

    ExampleClass ec = new ExampleClass();
    ec.setValue(12L);

    ParamValue<Long> pvString = new ParamValue<>();
    pvString.setParamName("value");

    // print 12
    System.out.println(pvString.getValue(ec));

Now, if I declare the "ParamValue" as a Point for example, it still works :

    ExampleClass ec = new ExampleClass();
    ec.setValue(12L);

    ParamValue<Point> pvPoint = new ParamValue<>();
    pvPoint.setParamName("value");

    // print 12
    System.out.println(pvPoint.getValue(ec));

But, as Point cannot be cast to Long, I expected some exception, like ClassCastException.

I know java compiler do some type erasure in compilation time, but I thought the compiler would automatically try to cast to Point, and fail, to the output of "pvPoint.getValue(ec)"

Can someone explain how this work ?

Thanks





Aucun commentaire:

Enregistrer un commentaire