ImanX
ImanX

Reputation: 816

Casting By Generics

Is there a way to cast an object to return Generic value of a method? I tried this way but to happen Casting exception:

public <S extends Super> S get(Class<S> clazz) {
    return (S) new Super();
}

public class Super {

}

public class Sub1 extends Super {

}

public class Sub2 extends Super {

}

Exception:

java.lang.ClassCastException: 
Cannot cast com.zarinak.app.model.Super to com.zarinak.app.model.Sub1

is there way?

Upvotes: 4

Views: 98

Answers (1)

Zachary
Zachary

Reputation: 1703

The way in which you attempt to cast a new Super object to an object type that has extended it is incorrect.

Say you want to create a Sub1 object - You instantiate a Super object using the constructor in the Super class and then tell the compiler that the object is actually Sub1, which it is not; it neither contains Sub1 specific methods or variables nor has been constructed using the Sub1 constructor. The compiler knows that the object is not Sub1 and will throw an error during runtime. While this may not be a problem with the current structure of your code, it will become problematic when Sub1 contains methods or variables that Super does not. If the compiler allowed this form of casting, attempting to invoke these methods down the track will be a significant issue.

This will achieve what you want. By constraining the S generic type to be an extension of Super, you effectively bypass instantiating a Super object and casting from there.

public <S extends Super> S get(Class<S> clazz) throws IllegalAccessException, InstantiationException {
    S s = clazz.newInstance();
    return s;
}

Having this as a method, without any additional body, is almost entirely pointless, and you may as well call clazz.newInstance(). Though, this does ensure that the class of the object extends Super.

Upvotes: 5

Related Questions