猿问

Java Class.cast()与强制转换运算符

在我的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 ++的语言构造?


慕森卡
浏览 2459回答 3
3回答

POPMUISE

首先,强烈建议您不要进行任何类型的演员表转换,因此应尽可能限制它!您将失去Java的编译时强类型功能的好处。无论如何,Class.cast()应主要在Class通过反射检索令牌时使用。写起来比较惯用MyObject myObject = (MyObject) object而不是MyObject myObject = MyObject.class.cast(object)编辑:编译时错误总体而言,Java仅在运行时执行强制检查。但是,如果编译器可以证明此类强制转换永远不会成功,则编译器可能会发出错误(例如,将一个类强制转换为非超类型的另一个类,并将最终的类类型强制转换为不在其类型层次结构中的类/接口)。在这里,由于Foo和Bar是不在彼此层次结构中的类,因此强制转换永远不会成功。

MYYA

尝试在语言之间翻译构造和概念总是有问题的,并且常常会产生误导。投射也不例外。特别是因为Java是一种动态语言,而C ++却有所不同。无论您如何执行,所有Java转换都在运行时完成。类型信息在运行时保存。C ++有点复杂。您可以将C ++中的一个结构强制转换为另一个结构,这只是对代表这些结构的字节的重新解释。Java不能那样工作。Java和C ++中的泛型也有很大的不同。不要过度担心自己在Java中如何进行C ++事情。您需要学习如何用Java方式做事。
随时随地看视频慕课网APP

相关分类

Java
我要回答