How does System.out.print() work?

后端 未结 9 2173
鱼传尺愫
鱼传尺愫 2020-11-27 03:40

I have worked with Java for a quite a long time, and I was wondering how the function System.out.print() works.

Here is my doubt:

Being a functi

相关标签:
9条回答
  • 2020-11-27 04:20

    Its all about Method Overloading.

    There are individual methods for each data type in println() method

    If you pass object :

    Prints an Object and then terminate the line. 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().

    If you pass Primitive type:

    corresponding primitive type method calls

    if you pass String :

    corresponding println(String x) method calls

    0 讨论(0)
  • 2020-11-27 04:21

    System.out is just an instance of PrintStream. You can check its JavaDoc. Its variability is based on method overloading (multiple methods with the same name, but with different parameters).

    This print stream is sending its output to so called standard output.


    In your question you mention a technique called variadic functions (or varargs). Unfortunately that is not supported by PrintStream#print, so you must be mistaking this with something else. However it is very easy to implement these in Java. Just check the documentation.


    And if you are curious how Java knows how to concatenate non-string variables "foo" + 1 + true + myObj, it is mainly responsibility of a Java compiler.

    When there is no variable involved in the concatenation, the compiler simply concatenates the string. When there is a variable involved, the concatenation is translated into StringBuilder#append chain. There is no concatenation instruction in the resulting byte code; i.e. the + operator (when talking about string concatenation) is resolved during the compilation.

    All types in Java can be converted to string (int via methods in Integer class, boolean via methods in Boolean class, objects via their own #toString, ...). You can check StringBuilder's source code if you are interested.


    UPDATE: I was curious myself and checked (using javap) what my example System.out.println("foo" + 1 + true + myObj) compiles into. The result:

    System.out.println(new StringBuilder("foo1true").append(myObj).toString());
    
    0 讨论(0)
  • 2020-11-27 04:22

    @ikis, firstly as @Devolus said these are not multiple aruements passed to print(). Indeed all these arguments passed get concatenated to form a single String. So print() does not teakes multiple arguements (a. k. a. var-args). Now the concept that remains to discuss is how print() prints any type of the arguement passed to it.

    To explain this - toString() is the secret:

    System is a class, with a static field out, of type PrintStream. So you're calling the println(Object x) method of a PrintStream.

    It is implemented like this:

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

    As wee see, it's calling the String.valueOf(Object) method. This is implemented as follows:

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

    And here you see, that toString() is called.

    So whatever is returned from the toString() method of that class, same gets printed.

    And as we know the toString() is in Object class and thus inherits a default iplementation from Object.

    ex: Remember when we have a class whose toString() we override and then we pass that ref variable to print, what do you see printed? - It's what we return from the toString().

    0 讨论(0)
  • 2020-11-27 04:22

    The scenarios that you have mentioned are not of overloading, you are just concatenating different variables with a String.

    System.out.print("Hello World");
    
    System.out.print("My name is" + foo);
    
    System.out.print("Sum of " + a + "and " + b + "is " + c); 
    
    System.out.print("Total USD is " + usd);
    

    in all of these cases, you are only calling print(String s) because when something is concatenated with a string it gets converted to a String by calling the toString() of that object, and primitives are directly concatenated. However if you want to know of different signatures then yes print() is overloaded for various arguments.

    0 讨论(0)
  • 2020-11-27 04:26

    You can convert anything to a String as long as you choose what to print. The requirement was quite simple since Objet.toString() can return a default dumb string: package.classname + @ + object number.

    If your print method should return an XML or JSON serialization, the basic result of toString() wouldn't be acceptable. Even though the method succeed.

    Here is a simple example to show that Java can be dumb

    public class MockTest{
    
    String field1;
    
    String field2;
    
    public MockTest(String field1,String field2){
    this.field1=field1;
    this.field2=field2;
    }
    
    }
    
    System.out.println(new MockTest("a","b");
    

    will print something package.Mocktest@3254487 ! Even though you only have two String members and this could be implemented to print

    Mocktest@3254487{"field1":"a","field2":"b"}
    

    (or pretty much how it appears in the debbuger)

    0 讨论(0)
  • 2020-11-27 04:39

    I think you are confused with the printf(String format, Object... args) method. The first argument is the format string, which is mandatory, rest you can pass an arbitrary number of Objects.

    There is no such overload for both the print() and println() methods.

    0 讨论(0)
提交回复
热议问题