【问题标题】:Why is x.toString different from (x: Any).toString为什么 x.toString 不同于 (x: Any).toString
【发布时间】:2014-05-15 08:29:20
【问题描述】:

接着How is ScalaRunTime.stringOf(x) not failing when x.toString fails?,怎么样

x.toString

不同于

(x: Any).toString

还有,怎么样

"" + x

REPL 会话示例:

> scala -cp joda-time-2.3.jar
Welcome to Scala version 2.11.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_05).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val dt = new org.joda.time.DateTime
warning: Class org.joda.convert.FromString not found - continuing with a stub.
warning: Class org.joda.convert.ToString not found - continuing with a stub.
warning: Class org.joda.convert.FromString not found - continuing with a stub.
warning: Class org.joda.convert.ToString not found - continuing with a stub.
dt: org.joda.time.DateTime = 2014-05-15T09:27:17.929+01:00

scala> (dt: Any).toString
res0: String = 2014-05-15T09:27:17.929+01:00

scala> "" + dt
res1: String = 2014-05-15T09:27:17.929+01:00

scala> dt.toString
java.lang.AssertionError: assertion failed: org.joda.convert.ToString
at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1410)
at scala.reflect.internal.Symbols$TypeSymbol.isNonBottomSubClass(Symbols.scala:3040)
at scala.reflect.internal.AnnotationInfos$AnnotationInfo.matches(AnnotationInfos.scala:305)
at scala.reflect.internal.AnnotationInfos$Annotatable$class.dropOtherAnnotations(AnnotationInfos.scala:68)
at scala.reflect.internal.AnnotationInfos$Annotatable$class.hasAnnotation(AnnotationInfos.scala:53)
at scala.reflect.internal.Symbols$Symbol.hasAnnotation(Symbols.scala:174)
at scala.tools.nsc.typechecker.Infer$class.improves$1(Infer.scala:61)
at scala.tools.nsc.typechecker.Infer$$anonfun$4.apply(Infer.scala:65)
at scala.tools.nsc.typechecker.Infer$$anonfun$4.apply(Infer.scala:65)

【问题讨论】:

    标签: scala inheritance overloading read-eval-print-loop


    【解决方案1】:

    您的其他问题的答案清楚地描述了问题,我再试一次并更详细地描述发生了什么。

    当您调用dt.toString 时,您实际上调用了DateTime 类的toString 方法,该类还包含此方法的重载版本。这会导致编译错误,而不是运行时错误,实际上是编译器中的错误(但它似乎在更新的 Scala 版本中得到修复,正如其他答案所提到的)

    (dt: Any).toString"" + dt 的情况下,您不是直接调用DateTime 中重载的toString 方法之一,而是Any 中定义的方法之一(实际上是java.lang.Object#toString)。编译器甚至看不到 DateTime 子类的重载 toString 方法 - 因此相应的错误不会造成任何问题。

    在运行时,由于动态调度,不是调用Any.toString 的实现,而是调用DateTime.toString。这种分派不是由 scalac 在编译时完成的,而是由 JVM 在运行时完成的。后者没有重载错误 - 因此不会发生错误。

    【讨论】:

    • 啊,编译和运行时的区别。我明白。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 2021-09-21
    • 1970-01-01
    • 2012-07-17
    相关资源
    最近更新 更多