Following on from How is ScalaRunTime.stringOf(x) not failing when x.toString fails?, how is
x.toString
different from
(x: Any).toString
Also, how about
"" + x
Example REPL session:
> 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)
Both these methods are used to convert a string. But yes, there is a difference between them and the main difference is that Convert. Tostring() function handles the NULL while the . ToString() method does not and it throws a NULL reference exception.
The reason for this is that the toString() method is defined for the class Object, and hence is inherited by all Java classes (we will discuss inheritance in more detail in Unit 8). This method is used to transform an object into a String.
The toString method is used to return a string representation of an object. If any object is printed, the toString() method is internally invoked by the java compiler. Else, the user implemented or overridden toString() method is called.
toString() method returns a string representing the specified object. The String object actually overrides the method of the same name from the Object object. This means that the original toString() method from the object Object is not inherited and the String version of the method is used instead.
The answer to your other question clearly describes the problem, I'll give it another shot and describe in more detail what is going on.
When you call dt.toString
you actually call the toString
method of the DateTime
class, which also contains an overloaded version of this method. This leads to a compilation error, not a runtime error, what actually is a bug in the compiler (but it seems to be fixed in a more recent Scala version as the other answer mentions)
In the case of (dt: Any).toString
or "" + dt
you are not directly calling one of the overloaded toString
methods in DateTime
but the one defined in Any
(which is in fact java.lang.Object#toString
). The compiler doesn't even see the overloaded toString
method of the DateTime
subclass - hence the corresponding bug doesn't make any problems.
At runtime, because of dynamic dispatch not the implementation of Any.toString
is called but DateTime.toString
. This dispatch is not done by scalac at compile time but by the JVM at runtime. The latter doesn't have the overloading bug - hence no error occurs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With