What are the differences between asInstanceOf[T] and (o: T) in Scala?

后端 未结 4 1084
南笙
南笙 2020-11-30 00:40

I saw that there are two methods to cast an object in Scala:

foo.asInstanceOf[Bar]
(foo: Bar)

When I tried, I found that asInstanceOf

4条回答
  •  长情又很酷
    2020-11-30 00:50

    There is example of the difference:

    1. Type cast (asInstanceOf) is a run-time operation with potentially run-time exception.
    2. Ascription is basically just an up-cast performed at compile-time.

    Example:

    class Parent() { def method() {} }
    class Child1 extends Parent() { def method1() {} }
    class Child2 extends Parent() { def method2() {} }
    
    // we return Parent type
    def getChild1() : Parent = new Child1()
    def getChild2() : Parent = new Child2()
    def getChild()  : Child1 = new Child1()
    
    (getChild1().asInstanceOf[Child1]).method1() // OK
    (getChild1().asInstanceOf[Child2]).method2() // runtime ClassCastException
    
    (getChild1() : Child2).method2() // compile-time error
    (getChild2() : Child2).method2() // compile-time error
    (getChild() : Parent).method1() // compile-time error
    (getChild()).method()  // OK
    
    // with asInstanceOf, we can cast to anything without compile-time error
    getChild1().asInstanceOf[String] // runtime ClassCastException
    getChild1().asInstanceOf[Int] // runtime ClassCastException
    

    We can also call method using multiple-dispatch:

    def prt(p: Parent) = println("parent")
    def prt(ch: Child1) = println("child")
    
    prt(new Parent()) // prints "parent"
    prt((new Child1()) : Parent) // prints "parent"
    prt(new Child1()) // prints "child"
    
    prt(new Parent().asInstanceOf[Child1]) // runtime ClassCastException
    prt(new Child1().asInstanceOf[Parent]) // prints "parent"
    

    We can define implicit conversion:

    // after definition of implicit conversions
    implicit def toChild1(p: Parent) : Child1 = new Child1()
    implicit def toChild2(p: Parent) : Child2 = new Child2()
    
    (getChild1() : Child2).method2() // OK - implicit conversion to Child2 in ascription
    (getChild2() : Child2).method2() // OK - implicit conversion to Child2 in ascription
    (getChild2()).method1() // OK - implicit conversion to Child1 when calling method1()
    (getChild2()).method2() // OK - implicit conversion to Child2 when calling method2()
    (getChild2() : Parent).method() // OK - no implicit conversion
    (getChild() : Parent).method1() // OK - implicit conversion to Child1 when calling method()
    
    getChild1().asInstanceOf[Int] // still runtime ClassCastException (no implicit conversion)
    

提交回复
热议问题