output is null when passing String str=null - java

public class StringTest
{
public static void main(String... args)
{
String str=null;
System.out.println(str);
}
}
why this code display null? when we pass reference variable into println() method it will call toString() method. For String class, toString() method will be call that returns current object. String str=null means no object is existing.

The documentation reports System.out.println(String):
Prints a String and then terminate the line. This method behaves as though it invokes print(String) and then println().
and the documentation for print(String) reports:
Prints a string. If the argument is null then the string "null" is printed. Otherwise, the string's characters are converted into bytes according to the platform's default character encoding, and these bytes are written in exactly the manner of the write(int) method.

Your answer is here:
Print a string. If the argument is null then the string "null" is
printed.
Note that "This method behaves as though it invokes print(String) and then println()"

Try
String str="";
null means theres nothing in that memory space... if you use "" that blank space inside will count, will make a space memory for that variable at same time will show nothing ( i think thats it)

Related

Printing without calling method [duplicate]

This question already has answers here:
The connection between 'System.out.println()' and 'toString()' in Java
(3 answers)
Closed 4 years ago.
it may seem as a very basic question, but I do not understand why the method toString is printed on the screen when I didn't even called it, I just instantiated a Car object. Thanks
public class Car {
public void m1() {
System.out.println("car 1");
}
public void m2() {
System.out.println("car 2");
}
public String toString() {
return "vroom";
}
}
public static void main(String[] args) {
Car myCar = new Car();
System.out.println(myCar);
}
The String.valueOf(Object) method is called implicitly, see the doc of println(Object x):
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().
and the doc of String.valueOf(Object obj):
if the argument is null, then a string equal to "null"; otherwise, the
value of obj.toString() is returned.
Because there's no System.out.println(Car) method, the Java compiler picks the closest match it can, which is System.out.println(Object). That calls String.valueOf on what you pass in to get the string version of it to print. String.valueOf uses the toString method of your object to get the string. From its documentation:
Returns:
if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.
In this line System.out.println(myCar) the toSring method is internally called because println calls at first String.valueOf(myCar) to get the printed object's string value. valueOf uses myCar.toString() if myCar is not null.
So the full flow would be like this:
System.out.println(myCar) > String.valueOf(myCar) > myCar.toString()

String Buffer method "toString"

what happens when you call "toString" method without a string variable to collect value that is returned?
For eg: here are two code snippets I tired. the first one gives the correct answer, the second gives a wrong answer but it still compiles. If "toString" method is meant to return a value, shouldn't I get a compiler error for the second block of code?
StringBuffer sb=new StringBuffer(s); //s is a string input taken from user
sb.reverse();
String rev=sb.toString();
if(s.equals(rev)){
System.out.println("yes");
/*second try*/
StringBuffer sb=new StringBuffer(s);
sb.reverse();
sb.toString();//what is happening here?
if(s.equals(sb)){
System.out.println("yes");
It is simple to understand.
In the first case, the value is returned and is being referenced by a variable so that you can make use of that value later on.
In the second case, the value is returned just like before but it is not being referenced by any variable. Thus, the value simply goes into waste and can not be used or manipulated later on.
sb.toString();//what is happening here?
You are converting the StringBuilder object to String which is good but you are not storing the return value to a String type and using it later in your equals call. You should do it the following way:
String reversedString = sb.toString();
if(s.equals(reversedString )){
Or simply
if(s.equals(sb.toString())){
Right now you are comparing s with sb using the equals method of String class. This method returns false if the object passed in as an argument is not an instance of String class. Since StringBuilder object sb is not an instance of String, the equals method returns false.
toString will return whatever the toString method of the object returns.
Try System.out.println(sb.toString); to see what it is returning.
StringBuffer#toString() returns a string, if you don't place that returned value in a variable then nothings happens and the information you've requested is gone.
.toString() is a method that returns a string, it does not convert that StringBuffer into a string.
if(s.equals(sb.toString())) would work because it is comparing s to the value of sb as a string, even though it is not assigning the value to variable.
In Java you don't have to check or store any return value.
sb.toString() is executed and the return value is truncated.
Please note that the method must be executed, because there might be side effects. To test it out, you might implement in your class:
#Override
public String toString() {
System.out.println("toStringTest");
return super.toString();
}
"toStringTest" will be put out!

Pass-by-value (StringBuilder vs String) [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
I do not understand why System.out.println(name) outputs Sam without being affected by the method's concat function, while System.out.println(names) outputs Sam4 as a result of the method's append method. Why is StringBuilder affected and not String? Normally, calling methods on a reference to an object affects the caller, so I do not understand why the String result remains unchanged. Thanks in advance
public static String speak(String name) {
name = name.concat("4");
return name;
}
public static StringBuilder test(StringBuilder names) {
names = names.append("4");
return names;
}
public static void main(String[] args) {
String name = "Sam";
speak(name);
System.out.println(name); //Sam
StringBuilder names = new StringBuilder("Sam");
test(names);
System.out.println(names); //Sam4
}
Because when you call speak(name);, inside speak when you do
name = name.concat("4");
it creates a new object because Strings are immutable. When you change the original string it creates a new object,I agree that you are returning it but you are not catching it.
So essentially what you are doing is :
name(new) = name(original) + '4'; // but you should notice that both the names are different objects.
try
String name = "Sam";
name = speak(name);
Of course now I think there is no need to explain why it's working with StringBuilder unless if you don't know that StringBuilder is mutable.
Looking at the Javadoc for String, one will read that
[...] String objects are immutable [...].
This means concat(String) does not change the String itself, but constructs a new String.
StringBuilders, on the other hand, are mutable. By calling append(CharSequence), the object itself is mutated.
Because String is immutable and hence String#concat does not modify the original String instance, it only returns a new String while the original is left unmodified, while StringBuilder is mutable and the change is reflected in the StringBuilder instance passed as parameter.
Okay, what is speak method doing?
First of all,
name.concat("4");
creates new object, which is equal to name, concatenated with "4".
So, the line
name = name.concat(4);
redefines local (for speak method) variable name.
Then you return the reference to this new value with
return name;
So, the original variable, passed within method is not modified, but the method returns modified value.
In the test method you actually modify variable without modifying the reference (the StringBuilder class is mutable, so variable if this type can be modified).
Then we can see another question arising: why StringBuilder.append returns value, where it can seem redundant. The answer to this question lies in the description of "builder" pattern, for which it is the usual way of implementing modification methods. See wikipedia on Builder pattern.
String is immutable in java. As soon as you invoke concat method on name. A new string is created and while you are playing with the old reference in System.out.println(name).If you want to use the modified string you should explicitly return the reference.
While StringBuilder is mutable and it returns the same reference always.
When you invoke speak(name) it computes the new value, but discards it.
If you replace it with
name = speak(name);
the result will be the one you expect.
With the StringBuilder, the object you pass is mutable: so
names.append(names);
changes the state of the current object (it also returns a reference to the same object, which is just a convenience to allow you to write code like names.append(...).append(...) etc.). So in the case of the StringBuilder, the object you are referencing when you call the method has actually changed, hence you see the changes.
In your method speak, the concat method returns a new String, the original object it was called on is unchanged (strings are immutable). As documented:
If the length of the argument string is 0, then this String object is returned. Otherwise, a String object is returned that represents a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string.
Calling name.concat("4") is the equivalent of name + "4".
In your test method the append method modifies the content of the StringBuilder. As documented:
The principal operations on a StringBuilder are the append and insert methods, which are overloaded so as to accept data of any type. Each effectively converts a given datum to a string and then appends or inserts the characters of that string to the string builder. The append method always adds these characters at the end of the builder; the insert method adds the characters at a specified point.
In your main method both name and names are still the same object as before the method call, but the content of name is unchanged as strings are immutable, while the content of names has been changed.
If instead you had used the return values of both methods, then you would have the result you were expecting.
First of all, String is an immutable class in Java. An immutable class is simply a class whose instances cannot be modified. All information in an instance is initialized when the instance is created and the information can not be modified.
Second, in java parameters are sent by values and not by reference.
In your method 'test' you don't need names = names.append("4"), instead names.append("4") will be enough .
If you check java docs for String object, you will see that most of the methods there, including concat, will generate a new String.
So to have on output Sam4 also for the String, you will need in main method to have this name = speak(name).
String
String is immutable ( once created can not be changed )object . The
object created as a String is stored in the Constant String Pool .
Every immutable object in Java is thread safe ,that implies String is
also thread safe . String can not be used by two threads
simultaneously. String once assigned can not be changed.
String demo = " hello " ; // The above object is stored in constant
string pool and its value can not be modified.
demo="Bye" ; //new "Bye" string is created in constant pool and
referenced by the demo variable // "hello" string still
exists in string constant pool and its value is not overrided but we
lost reference to the "hello"string
StringBuilder
StringBuilder is same as the StringBuffer , that is it stores the
object in heap and it can also be modified . The main difference
between the StringBuffer and StringBuilder is that StringBuilder is
also not thread safe. StringBuilder is fast as it is not thread safe
.
For more details check this
Conclusion:
You don't need to re-assign the value again to StringBuilder as it is already a reference
test method should be
public static void test(StringBuilder names) {
names.append("4");
}
but speak should be
String name = "Sam";
name = speak(name);

Invoking method issue in Java

public class Tester {
private String text;
public void text() {
text = "abc";
}
public static void main(String[] args) {
Tester test = new Tester();
System.out.println(test.text);
}
}
Why does this print null? Also, if I write test.text() inside the print command, why there is an error? I thought I needed to invoke the method like that.
null because private String text; is null as you have not made call to your public void text() which sets the value of String text
Make call to your text() before printing
Tester test=new Tester();
test.text();
System.out.println(test.text);
Output:
abc
PS.
As per comment => "Can I directly write System.out.println(test.text())? "
For that set return type to String and return String from it
So Change your code to
public String text() {
return "abc";
}
And
Test test = new Test();
System.out.println(test.text());
Output:
abc
It is printing null because the default value of all Class types is null, you have not set text and still trying to print.
if you want to print abc then follow either of the following ways
1 call you text method explicitly like test.text();
2 initialize yourtext in constructor as follows
Tester(){
text="abc";
}
Your String object is assigned null at construction time - that is, when you declare new Tester(), your text field is assigned null. This is the default value of all object types, and all primitives are assigned zero (or false, if the primitive is a boolean).
Nothing's assigned to it, and the default behavior of printing out null is to print the literal text "null".
As for your second question - the reason that this won't work:
System.out.println(test.text());
text() is a method call that returns void, or nothing. There's nothing that is returned as a result of the method call, so nothing can be printed out.
You would want to move your call to text() before any print statements, so the field is properly populated:
Tester test = new Tester();
test.text();
System.out.println(test.text);
...and, there is a convention for something like this: if you want the field to be populated at construction time, create a constructor that accepts it as an argument.
public Tester(String text) {
this.text = text;
}
When you construct it, you don't need to worry about any extraneous call to text(); just print the field.
Tester test = new Tester("abc");
System.out.println(test.text);
You should call test.text(); firstly to give test a value.
As text is a class variable so it is by default initialized to null.If it would be int then it would have been initialized to 0;
In your program you are not calling text() so the value of text is not changed.Now in the main method you are printing text so its printing null;
Also, if I write test.text() inside the print command, why there is an error?
this is because the return type of text() is void

How does System.out.print() work?

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 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.
It is a very sensitive point to understand how System.out.print works.
If the first element is String then plus(+) operator works as String concate operator. If the first element is integer plus(+) operator works as mathematical operator.
public static void main(String args[]) {
System.out.println("String" + 8 + 8); //String88
System.out.println(8 + 8+ "String"); //16String
}
Evidently, the compiler was made in a confusing way although the compiler developers thought they added some smartness. The true smartness they should really add is to look entire argument and interpret + operator consistently. For example, System.out.println(1+2+"hello"+3+4); should output 3hello7 instead of 3hello34
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.
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
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)
#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().
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.

Categories