在我的C ++时代里,学习过有关C风格的强制转换运算符的弊端后,我很高兴首先发现Java 5中java.lang.Class已经获得了一种cast方法。我以为最终我们有了一种面向对象的处理铸造的方法。事实证明Class.cast与static_castC ++不同。更像是reinterpret_cast。它不会在预期的地方生成编译错误,而是会推迟到运行时。这是一个演示不同行为的简单测试用例。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 ); } }}所以,这些是我的问题。应该Class.cast()放逐到泛型土地吗?那里有很多合法用途。Class.cast()使用时,编译器是否应该生成编译错误,并且可以在编译时确定非法条件?Java是否应提供强制转换运算符作为类似于C ++的语言构造?
3 回答
POPMUISE
TA贡献1765条经验 获得超5个赞
首先,强烈建议您不要进行任何类型的演员表转换,因此应尽可能限制它!您将失去Java的编译时强类型功能的好处。
无论如何,Class.cast()应主要在Class通过反射检索令牌时使用。写起来比较惯用
MyObject myObject = (MyObject) object
而不是
MyObject myObject = MyObject.class.cast(object)
编辑:编译时错误
总体而言,Java仅在运行时执行强制检查。但是,如果编译器可以证明此类强制转换永远不会成功,则编译器可能会发出错误(例如,将一个类强制转换为非超类型的另一个类,并将最终的类类型强制转换为不在其类型层次结构中的类/接口)。在这里,由于Foo和Bar是不在彼此层次结构中的类,因此强制转换永远不会成功。
MYYA
TA贡献1868条经验 获得超4个赞
尝试在语言之间翻译构造和概念总是有问题的,并且常常会产生误导。投射也不例外。特别是因为Java是一种动态语言,而C ++却有所不同。
无论您如何执行,所有Java转换都在运行时完成。类型信息在运行时保存。C ++有点复杂。您可以将C ++中的一个结构强制转换为另一个结构,这只是对代表这些结构的字节的重新解释。Java不能那样工作。
Java和C ++中的泛型也有很大的不同。不要过度担心自己在Java中如何进行C ++事情。您需要学习如何用Java方式做事。
添加回答
举报
0/150
提交
取消