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 function, it has a declaration somewhere in the io package. But how did Java developers do that, since this function can take in any number of arguments and any argument types no matter how they are arranged? e.g:
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);
No matter what is the datatype of variables a, b, c, usd, foo
or how they are passed, System.out.print()
never throws an error.
For me, I have never worked on any project where the requirement was like this. Provided, if I get a requirement like this, I really don't know how to solve it.
Can anyone explain to me how it's done?
System. out. println does not print to the console, it prints to the standard output stream ( System. out is Java's name of the standard output stream).
print(): print() method in Java is used to display a text on the console. This text is passed as the parameter to this method in the form of String. This method prints the text on the console and the cursor remains at the end of the text at the console.
System is a final class which is present in java. lang package. out is the reference of PrintStream class and a static member of System class.
The println() terminates the current line by writing the line separator string. The print() method just prints the given content.
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());
Even though it look as if System.put.print...()
take a variable number of arguments it doesn't. If you look closely, the string is simply concatenated and you can do the same with any string. The only thing that happens is, that the objects you are passing in, are implicitily converted to a string by java calling the toString()
method.
If you try to do this it will fail:
int i = 0; String s = i; System.out.println(s);
Reason is, because here the implicit conversion is not done.
However if you change it to
int i = 0; String s = "" + i; System.out.println(s);
It works and this is what happens when using System.put.print...()
as well.
If you want to implement a variable number of arguments in java to mimimc something like C printf
you can declare it like this:
public void t(String s, String ... args) { String val = args[1]; }
What happens here is that an array of Strings is passed in, with the length of the provided arguments. Here Java can do the type checking for you.
If you want truly a printf then you have to do it like this:
public void t(String s, Object ... args) { String val = args[1].toString(); }
Then would you have to cast or interpret the arguments accordingly.
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