Reputation: 1671
I am creating a function where I want to register different type of Exception in external library. They already have a method defined which accept Class as parameter.
I want to read different exception from configuration and register it, however I am getting typecast warning. I can ignore/suppress it, but is there any way to not suppress it?
The exact warning is Type safety: Unchecked cast from Class<capture#2-of ?> to Class<? extends Throwable>
Here is the sample code which throws warning
Class<?> exceptionClass = Class.forName("java.lang.Exception"); //Getting this value from Config. Let us assume that config is good and I get only valid classname which extends Throwable
registerExceptionInExternalLibrary((Class<? extends Throwable>)exceptionClass); // Getting the warning here
I think I cannot do casting here, since there is not object. But if I do not use casting, then I get this warning
The method registerExceptionInExternalLibrary(Class<? extends Throwable>) in the type XXXXX is not applicable for the arguments (Class<capture#2-of ?>)
Here is that code sample
Class<?> exceptionClass = Class.forName("java.lang.Exception"); //Getting this value from Config. Let us assume that config is good and I get only valid classname which extends Throwable
registerExceptionInExternalLibrary(exceptionClass); // Getting the warning here
Upvotes: 0
Views: 1633
Reputation: 73568
You can use Class.asSubClass for this.
Class<?> exceptionClass = Class.forName("java.lang.Exception");
registerExceptionInExternalLibrary(exceptionClass.asSubclass(Throwable.class));
The complete code of the method is as follows and shows you're just offloading the cast (and warning suppression) to a JDK method, so there's nothing too magical about it. But it's very handy in map()
chains, and works nicely here too. Also it does verify that you're making a correct cast with isAssignableFrom
, which is the extra functionality that you'd forget to write if you just did the cast yourself and suppressed the warning.
@SuppressWarnings("unchecked")
public <U> Class<? extends U> asSubclass(Class<U> clazz) {
if (clazz.isAssignableFrom(this))
return (Class<? extends U>) this;
else
throw new ClassCastException(this.toString());
}
Upvotes: 5
Reputation: 371
There's a similar question about unchecked casts.
In short, the compiler can't be sure if the exceptionClass
is a variable of type Class<? extends Throwable>
, so you will get a warning anyway.
You can use @SuppressWarnings annotation with limited scope:
@SuppressWarnings("unchecked")
Class<? extends Throwable> exceptionClass = (Class<? extends Throwable>)Class.forName("java.lang.Exception");
The annotation here will not affect the entire method.
Upvotes: 0