Java Class.cast()vs. cast运算符 [英] Java Class.cast() vs. cast operator

查看:110
本文介绍了Java Class.cast()vs. cast运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的C ++日教授C风格的转换运算符的邪恶,我很高兴首先发现在Java 5 java.lang.Class



我想最后我们有一个处理铸造的OO方式。



结果 Class.cast 与C ++中的 static_cast 不同。它更像是 reinterpret_cast 。它不会产生预期的编译错误,而是延迟到运行时。这里是一个简单的测试用例来演示不同的行为。

 包测试; 

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;
}

{
//编译错误
final Bar bar_ref = foo;
}
{
//编译错误
final Bar bar_ref =(Bar)foo;
}

try
{
//!编译正常,运行时异常
Bar.class.cast(foo);
}
catch(final ClassCastException ex)
{
assertTrue(true);
}

{
final Bar bar_ref = bar_subclass;
}

try
{
//编译正常,运行时异常,相当于C ++ dynamic_cast
final BarSubclass bar_subclass_ref =(BarSubclass)bar;
}
catch(final ClassCastException ex)
{
assertTrue(true);
}
}
}


  1. 应该 Class.cast()

  2. 如果使用 Class.cast()时编译器会产生编译错误,



  3. < =h2_lin>解决方案

    我只使用Class.cast(Object)来避免在generic land中出现警告。我经常看到方法做这样的事情:

      @SuppressWarnings(unchecked)
    < T& T doSomething(){
    Object o;
    // snip
    return(T)o;
    }

    通常最好将它替换为

     < T> T doSomething(Class< T> cls){
    Object o;
    // snip
    return cls.cast(o);
    }

    这是Class.cast(Object)的唯一用法



    关于编译器警告:我怀疑Class.cast(Object)对于编译器不是特殊的。它可以优化时使用静态(即Foo.class.cast(o)而不是cls.cast(o)),但我从来没有见过任何人使用它 - 这使得编译这种优化编译器的努力有点毫无价值。


    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.

    1. Should Class.cast() be banished to Generics land? There it has quite a few legitimate uses.
    2. Should compilers generate compile errors when Class.cast() is used and illegal conditions can be determined at compile time?
    3. Should Java provide a cast operator as a language construct similar to C++?

    解决方案

    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 usecase 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.

    这篇关于Java Class.cast()vs. cast运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆