5

A seguito di How is ScalaRunTime.stringOf(x) not failing when x.toString fails?, come èPerché x.toString diverso da (x: Qualsiasi) .ToString

x.toString 

diverso da

(x: Any).toString 

Inoltre, come su

"" + x 

Esempio sessione 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) 

risposta

8

La risposta alla tua altra domanda descrive chiaramente il problema, darò un altro scatto e descriverò più in dettaglio cosa sta succedendo.

Quando si chiama dt.toString si chiama in realtà il metodo della classe DateTime, che contiene anche una versione di overload di questo metodo toString. Questo porta ad un errore di compilazione, non è un errore di runtime, quello che in realtà è un bug nel compilatore (ma sembra essere fissato in un più recente versione di Scala come l'altra risposta menziona)

Nel caso di (dt: Any).toString o "" + dt non si sta chiamando direttamente uno dei metodi sovrastimati toString in DateTime ma quello definito in Any (che di fatto è java.lang.Object#toString). Il compilatore non vede nemmeno il metodo toString sovraccarico della sottoclasse DateTime - quindi il bug corrispondente non crea problemi.

In fase di esecuzione, a causa della spedizione dinamica, non viene chiamata l'implementazione di Any.toString ma DateTime.toString. Questa spedizione non viene eseguita da scalac in fase di compilazione ma da JVM in fase di runtime. Quest'ultimo non ha il bug di sovraccarico - quindi non si verifica alcun errore.

+0

Ah, la distinzione di compilazione e runtime. Capisco. Grazie. –

Problemi correlati