Java Class.cast() vs. cast operator
casting, compiler-warnings, generics, java
Solution
I've only ever used `Class.cast(Object)` to avoid warnings in "generics land". I often see methods doing things like this:
@SuppressWarnings("unchecked")
<T> T doSomething() {
Object o;
// snip
return (T) o;
}
It's often best to replace it by:
<T> T doSomething(Class<T> cls) {
Object o;
// snip
return cls.cast(o);
}
That's the only use case for `Class.cast(Object)` I've ever come across.
Regarding compiler warnings: I suspect that `Class.cast(Object)` isn't special to the compiler. It could be optimized when used statically (i.e. `Foo.class.cast(o)` rather than `cls.cast(o)`) but I've never seen anybody using it - which makes the effort of building this optimization into the compiler somewhat worthless.
Problem
Having being taught during my C++ days about evils of the C-style cast operator I was pleased at first to find that in Java 5 `java.lang.Class` had acquired a `cast` method. I thought that finally we have an OO way of dealing with casting. Turns out `Class.cast` is not the same as `static_cast` in C++. It is more like `reinterpret_cast`. It will not generate a compilation error where it is expected and instead will defer to runtime. Here is a simple test case to demonstrate different behaviors. ``` package test; import static org.junit.Assert.assertTrue; import org.junit.Test; public class TestCast { static final class Foo { } static class Bar { } static final class BarSubclass extends Bar { } @Test public void test ( ) { final Foo foo = new Foo( ); final Bar bar = new Bar( ); final BarSubclass bar_subclass = new BarSubclass( ); { final Bar bar_ref = bar; } { // Compilation error final Bar bar_ref = foo; } { // Compilation error final Bar bar_ref = (Bar) foo; } try { // !!! Compiles fine, runtime exception Bar.class.cast( foo ); } catch ( final ClassCastException ex ) { assertTrue( true ); } { final Bar bar_ref = bar_subclass; } try { // Compiles fine, runtime exception, equivalent of C++ dynamic_cast final BarSubclass bar_subclass_ref = (BarSubclass) bar; } catch ( final ClassCastException ex ) { assertTrue( true ); } } } ``` So, these are my questions. - Should `Class.cast()` be banished to Generics land? There it has quite a few legitimate uses. - Should compilers generate compile errors when `Class.cast()` is used and illegal conditions can be determined at compile time? - Should Java provide a cast operator as a language construct similar to C++?