Provide a get method that will throw a ReflectionException wrapping a ClassCastException if the cast fails
When writing code such as:
SomeClassType someObject = Reflect.on(className).create(properties).get();
It is not possible to catch the ClassCastException that might be thrown from the casting code in get().
It would be nice, in my opinion if there was an attempt to catch a ClassCastException here and wrap it in a ReflectionException so calling code can handle that case.
There's no way to catch that ClassCastException as it occurs at the call site when you assign the value.
We could, however, add a method like this:
public <T> T get(Class<T> type) {
try {
return type.cast(object);
}
catch (ClassCastException e) {
throw new ReflectException(e);
}
}
However, I'm not so sure if the asymmetry of thrown exceptions is really desireable...
Right, I can understand that concern. One of the reasons I picked up the library earlier this morning was to try and refactor some code to avoid all those nasty other exceptions when really all I cared about was "did the class specified instantiate and cast successfully". There's something really nice about capturing all of that within:
try {
SomeClassType someObject = Reflect.on(className)
.create(properties)
.get();
} catch (ReflectionException e) {
// do stuff
}
Rather than having to unwrap from get() as an Object and instanceof or to do a comparison with type().
Appreciate that there are many more things than just my use case to consider and I am quite new to reflection so there may be a better way I've missed, just thought I'd lay out my thoughts and you can make a decision on that.
Thanks for the quick response!
Sure. When we added that <T> T get() method, we aimed for the "quick win". In the meantime, we don't apply that practice any longer. It's in fact a very bad practice...
ideally, we'd remove the generic parameter on that particular method and make it Object get(), while adding the suggestion from above, although that would be breaking backwards-compatibility.
Having said so, we'll find a solution :-) For the time being: workarounds:
try {
SomeClassType someObject = Reflect.on(className)
.create(properties)
.get();
} catch (ReflectionException | ClassCastException e) {
// do stuff
}
// or...
} catch (RuntimeException e) {
Sure. When we added that
<T> T get()method, we aimed for the "quick win". In the meantime, we don't apply that practice any longer. It's in fact a very bad practice...Ideally, we'd remove the generic parameter on that particular method and make it
Object get(), while adding the suggestion from above, although that would be breaking backwards-compatibility.
Could you elaborate why it's bad practice to use the generic get method? Is it because it hides compile time warnings about unchecked casts?
Could you elaborate why it's bad practice to use the generic get method? Is it because it hides compile time warnings about unchecked casts?
Yes. This type of generic method only makes sense when you're 100% sure there cannot be any ClassCastException. e.g. in java.util.Collections:
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
Since this is an empty, unmodifiable list, the type will be correct for any bindings of <T>. This is not the case in <T> T get() of jOOR.
I don't even remember creating this so I'm going to go ahead and close it. It can always be re-opened again if anyone finds and cares about it.