Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is x.toString different from (x: Any).toString

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)
like image 392
Dale Wijnand Avatar asked May 15 '14 08:05

Dale Wijnand


People also ask

What is the difference between toString and string?

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.

Is toString inherited by all classes?

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.

What is the toString method and why is it used?

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.

What is the difference between string and toString in JS?

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.


1 Answers

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.

like image 170
kiritsuku Avatar answered Oct 19 '22 23:10

kiritsuku