Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中这两种强制转换方法的区别是什么?_Java_Casting - Fatal编程技术网

Java中这两种强制转换方法的区别是什么?

Java中这两种强制转换方法的区别是什么?,java,casting,Java,Casting,Java中这两种强制转换方法的区别是什么 (CastingClass)objectToCast CastingClass.class.cast(objectToCast) Class#cast(Object)的来源如下: public T cast(Object obj) { if (obj != null && !isInstance(obj)) throw new ClassCastException(); return (T) obj; } 因此,cast基本上是

Java中这两种强制转换方法的区别是什么

  • (CastingClass)objectToCast

  • CastingClass.class.cast(objectToCast)

  • Class#cast(Object)
    的来源如下:

    public T cast(Object obj) {
    if (obj != null && !isInstance(obj))
        throw new ClassCastException();
    return (T) obj;
    }
    

    因此,
    cast
    基本上是一个cast操作的通用包装器,但我仍然不明白为什么需要一个方法。

    因为当
    t
    是一个通用类型参数时(由于类型擦除),您不能只编写
    (t)objectToCast
    。Java编译器将允许您这样做,但是
    T
    在那里将被视为
    Object
    ,因此强制转换将始终成功,即使您正在强制转换的对象实际上不是
    T
    的实例

    对于静态链接的类,只能使用第一种形式


    在许多情况下,这还不够——例如,您可能已经使用反射获得了类实例,或者它被作为参数传递给了您的方法;因此出现了第二种形式。

    第一种是普通铸造。它要求转换到的类型在编译时已知。它在编译时验证强制转换是否正确,并在运行时检查(如果要强制转换到的类型不是泛型)强制转换是否正确

    第二个使用反射api。它要求在运行时已知要强制转换到的类。它不会在编译时验证任何内容,但总是在运行时检查强制转换是否正确

    类型参数仅在编译类型时已知,因此不能对类型参数使用第二种方法(表达式
    T.class
    不编译)

    动态加载的类(例如带有Class.forName(String))仅在运行时已知,因此不能使用第一种方法

    编辑:但是,正如Pavel指出的,强制转换到动态加载的类是没有意义的。我同意,
    Class.cast(Object)
    唯一真正有用的功能是对一个类型参数进行强制转换,而您恰好有一个Class对象可用


    如果要强制转换到的类型不包含类型参数,则第一种方法更好,因为额外的编译时检查可以捕获错误,在运行时不会丢失类型安全性,并且可以获得较短的启动语法。

    您可以找到一个使用
    Class#cast()
    的使用示例。它可能会提供新的见解。

    在第一篇文章中,您将硬编码铸造类

    ( ClassToCast ) objectToCast;
    
    在第二种情况下,铸造类可能是一个参数:

    Class toCast = getClassToCast();
    
    toCast.cast( objectToCast );
    

    好的,我刚刚意识到可以使用
    cast
    来强制转换到基本类型的包装器。例如,
    整数i=int.class.cast(“1234”)
    @simmbot:你可以写这个,但它不会做你最可能认为它会做的事情。试试看。这会抛出一个ClassCastException,因为String不是Integer类型。在这种情况下,您需要
    Integer.valueOf(“1234”)
    。嗨,Pavel,您介意再解释一下吗
    cast
    似乎就是这样做的:
    return(T)obj你肯定能写出来。它只是发出一个编译器警告。@meriton:说得好,编辑好了。我想说的是,cast仍然不会做它真正应该做的事情。@simmbot:它会做,但在做之前它也会做一个显式的类型检查(因为cast本身不会这样做)。因此,它与普通的
    (Type)对象
    cast一样是类型安全的-如果对象实际扩展或实现了
    T
    ,它将只返回类型为
    T
    的引用,否则它将抛出。@PavelMinaev但“静态”cast
    (Type)对象
    。如果
    对象
    不是
    类型
    的实例,那么将抛出
    类castException,对吗?那么这两种方式有什么区别呢?对。在第一种形式中,您正在源代码中“烘焙”强制转换。不重新编译就无法更改它。第二种形式允许您尝试对任意类进行强制转换。但是,对于动态加载的类,为什么需要强制转换呢?强制转换通常是强制表达式具有某种类型,但在动态加载类的情况下,您事先不知道该类型。毕竟,如果您有一个动态加载的类,您不知道对
    class.cast()
    的调用中的
    t
    是什么,所以您只需要使用原始版本,然后返回类型将是
    Object
    ——这不是什么强制转换。它会检查类型,但肯定
    Class.isInstance()
    是一种更好的方法。总而言之,在我看来,这只是针对泛型的。