-1

Why is the output? : Sphere 0

Somehow it's calling the toString() method implicitly? How does this work ?

class BerylliumSphere {
    private static long counter = 0;
    private final long id = counter++;
    public String toString() { 
        return "Sphere " + id;
    }
}

public class Test {
    public static void main (String[] args) {
        BerylliumSphere spheres = new BerylliumSphere();
        System.out.println(spheres);
    }
}

// output: Sphere 0 
Timothy
  • 346
  • 6
  • 18
  • There is no magic and it's not "Java" that does it, but the `println` method. You can implement such a method yourself. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/io/PrintStream.java#820 – Marko Topolnik Oct 04 '16 at 08:27
  • 1
    Passing object in println() always gives the toString representation – Kahn Oct 04 '16 at 08:28
  • 1
    This is not "implicit", it is "explicit", just look what `println` does. – Tom Oct 04 '16 at 08:30
  • @Tom Hey tom it is implicitly calling because I never called the toString() method in the main method so it happens internally. – Timothy Oct 04 '16 at 15:56
  • @TimothyKimman Just because you don't call it, it means that this is implicit. The call of `toString()` is explicitly done in the source of `String`. – Tom Oct 04 '16 at 16:46
  • Implicit is stuff defined by the JLS, like abstract methods in interfaces are *implicitly* `public` even if one doesn't add an access modifier, or that `super()` will *implicitly* called in a subclass constructor if not done explicitly. – Tom Oct 04 '16 at 16:53
  • Thanks, also kudos for JLS reference – Timothy Oct 04 '16 at 17:06

3 Answers3

5

System.out is a PrintStream instance that is a static member of System. The PrintStream class has a function println() that accepts an argument of type Object. That function, in Open JDK, looks like the following:

public void println(Object x) {
     String s = String.valueOf(x);
     synchronized (this) {
         print(s);
         newLine();
     }
}

And if you look at String.valueOf(), which accepts an argument of type Object, you can see:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

There is no magic. It's just a Java class that calls toString on objects.

Further Reading

Tom
  • 16,842
  • 17
  • 45
  • 54
christopher
  • 26,815
  • 5
  • 55
  • 89
  • But I don't get why it is using the toString() method I wrote in the BerylliumSphere class since I never called it? – Timothy Oct 04 '16 at 16:27
  • 1
    You need to learn about Polymorphism my friend! By creating your own toString(), you have overridden the implementation of the same function in all superclasses. – christopher Oct 04 '16 at 16:29
3

Here is what System.out.println does: https://docs.oracle.com/javase/7/docs/api/java/io/PrintStream.html#println%28java.lang.Object%29

It says the following:

This method calls at first String.valueOf(x) to get the printed object's string value, then behaves as though it invokes print(String) and then println().

And here is what String.valueOf does: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#valueOf%28java.lang.Object%29

And it says:

If the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.

In short, printing an object will result in calling its toString method and printing what it returns.

uoyilmaz
  • 3,035
  • 14
  • 25
  • But I don't get why it is using the toString() method I wrote in the BerylliumSphere class since I never called it? – Timothy Oct 04 '16 at 16:15
1

When you try to System.out.println(spheres) it looks like following:

public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }

And this is valueOf(Object obj) method:

public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }