Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

q from jiris.com

 
JayaSiji Gopal
Ranch Hand
Posts: 303
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the output of trying to compile and run the following code?
(Select one correct answer)
--------------------------------------------------------------------------------

class Test001
{
int i;

public Test001(int i) { this.i = i; }

public String toString()
{
if(i == 0) return null;
else return "" + i;
}

public static void main(String[ ] args)
{
Test001 t1 = new Test001(0);
Test001 t2 = new Test001(2);
System.out.println(t1);
System.out.println(t2);
}
}

--------------------------------------------------------------------------------

A: The code does not compile.
B: The code compiles but throws exception when run.
C: The code compiles and run successfully with output:
null
2
D: The code compiles and run successfully with output:
0
2

I answered c, but the correct answer is b.
can somebody tell me y?
 
Aneesha Singh
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because, I think, in the line:

System.out.println(t1);

NULL is returned, throwing a runtime exception.
 
Premkumar Gopal
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I believe the reason being :
toString() method is called whenever we try to call the object reference. In this case, the toString method specifically sets it to null
for the parameter 0 ( passed to the constructor).

If we created Test001 t3 = null ; we neither get compiler error and nor runtime exception.
Maybe Gurus can throw more light(any other explanation will help me to clear my ignornace and shape me better to prepare well for scjp ).
 
Premkumar Gopal
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was executing the code myself and the below explanation will might help better to understand the nullpointer exception :
Whenever any method is executed on the object whose value is null, nullpointer exception is thrown. Having said that, when we invoke the println method ,

public void write(String str) throws IOException
{
write(str, 0, str.length());
}


of the Writer class (got from the exception trace). Since str value is set to null, str.length() throws null pointer exception.
Hope this helps.
 
Atul Chandran
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
System.out.println(null);//will result in a compiler error

The compiler is unable to decide which method to call println(char[]) or println(String). Or in the words of the compiler "reference to println is ambiguous".

But in this case the compiler cannot determine the value being printed. The actual method call (call to toString()) is deferred until runtime. The first call returns null and the JVM is unable to decide which println to call and hence it throws a NullPointerException.

I think this is the case.But I am not sure about it??




 
sanjeevmehra mehra
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


output:

null
null
null

What is the reason for
NullPointerException for first posting because of
System.out.printn(t1);

[ November 22, 2004: Message edited by: sanjeevmehra mehra ]
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Simply put: the method toString() should return a reference to a String object that is a human readable representation of the object on which it is called. null is not a reference to such a String object. Whatever is inside the System.out.println() method which is calling the toString() method is obviously getting fed up and throwing the NullPointerException. So this is clearly a case where the contract of the toString() method has been broken.
 
Premkumar Gopal
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sanjeev,
With reference to your
"... System.out.println(t1) ; .."

Here the passed object is null which is determined at the runtime unlike System.out.println(null) ( earlier said by Atul...in which case we get a compiler error as jvm could not figure out which method to use).

However when we use the statment (from the first posting)

System.out.println(t1)...here do note that the toString() method is called which invokes the series of classes ( Stacktrace I got :

java.lang.NullPointerException
at java.io.Writer.write(Writer.java:126)
at java.io.PrintStream.write(PrintStream.java:303)
at java.io.PrintStream.print(PrintStream.java:462)
at java.io.PrintStream.println(PrintStream.java:599)
at javaranch.Test001.main(Test001.java:31)
Exception in thread "main"

java.lang.NullPointerException
at java.io.Writer.write(Writer.java:126)
at java.io.PrintStream.write(PrintStream.java:303)
at java.io.PrintStream.print(PrintStream.java:462)
at java.io.PrintStream.println(PrintStream.java:599)
at javaranch.Test001.main(Test001.java:31)
Exception in thread "main"


When I look into the source code of the abstract class Writer the lines 125 : 127 are

125 : public void write(String str) throws IOException {
126 :write(str, 0, str.length());
127 : }

str.length() method is invoked, which in this case happens to be null, and any method invoked on the null returs NullPointerExcpetion.

Thanks
 
sanjeevmehra mehra
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks you all for sharing your knowledge but still I am not able to get one point

Output
null
NullPointerException

in both cases it is calling toString() method
one is displaying "null"
other is throwing "NullPointerException" at runtime.
Not able to figure out difference b/w two method calls.
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm confused as well.

The Java 1.5.0 API doc says:
public void print(String s)

Print 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.
 
Hai Le
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i don't really understand why it related to toString() method. What we actually do in the code is to create an instance of class Test001.
How does it relate to toString() method which cause Exception...!!!???!!

Sincere
 
Premkumar Gopal
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This thread is making me to think more and more ...

Even though the toString method is called into action, how the object is invoked plays a vital role. One has to take into account of the
println/print method of the java.io.PrintStream class is made use of. This is how I understood after going through the methods :

public class test{

public String toString(){return null;}

public static void main(String [] args)
System.out.println(new test().toString());
//calling toString() method
System.out.println(new test());
//calling toString() method} }


When we call new test().toString() , we are making use of the
public void print(String s)
of the PrintStream class - which says
if he argument is null then sthe string null is printed...

which is what happening here...

however when call new test(), we are making use of the
public void print(Object obj)
of the PrintStream class -

which in turn calls String.value of
Please note that here we are still talking about the object in this case which is t2. Since t2 is not null (note we are returning only null as part of the toString() method and not the object reference ), we are passing the object t2 to the method ( The code that actually gets executed is

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

and returns null . To make myself clear, I thought I will delineate how the various classes are called

1) System.out.print(new test()) which is the same as calling
System.out.println(new test()) except for the return and line feed :

( PrintStream class )
public void print(Object obj) {
write(String.valueOf(obj));
}

2) This in turn calls (..String Class)

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

the value got out of the above method is null which in goes to

private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();

}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}


When textOut.write(s) is called (note we are passing the value null) and this is made use of in writer class as



public void write(String str) throws IOException {
write(str, 0, str.length());
}


here we are checking the length which is null.length() and this causes the nullpointer exception.

Hope this explains little better than what I put earlier. I believe anyone who goes through the api and ( the unzipped version of src.zip file of jre) can figure out.
Bottom line : parameter passed to println method (whether it is an object or the String) determines the method of execution...

Thanks
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hai Le asked:
i don't really understand why it related to toString() method. What we actually do in the code is to create an instance of class Test001.
How does it relate to toString() method which cause Exception...!!!???!!


When you perform an operation requiring a String and you supply a reference to a class, Java adds ".toString()" automatically.

If your class definition doesn't include a toString() method, it inherits one from its superclass, from Object if necessary.

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

getClass().getName() + '@' + Integer.toHexString(hashCode())

[ November 22, 2004: Message edited by: Mike Gershman ]
 
Jay Pawar
Ranch Hand
Posts: 411
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried running this code in textpad and it gives me runtime exception. However, if I run this is code IBM Websphere I get output of

null
2

That is surprising.
 
Premkumar Gopal
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jay,
I believe you are making use of Websphere 5/5.1 (in which case the default jre is not 1.4). I am thinking that might be the reason. I do use Websphere and I point it to 1.4.2 JRE.

Hope this helps
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
From the Java 1.5.0 API doc:


This is the actual code for PrintStream.print:



This is the actual code for String.valueOf:


-------------------------------------------------------------------
I can now see why this works:

but this fails:


println() passes its argument t1, which is a subclass of Object, to print()

print() passes the argument to String.valueOf()

In the first case, String.valueOf() sees that t1 == null and returns the String "null", which gets printed.

In the second case, String.valueOf() sees that t1 != null,
so it calls t1.toString(), expecting to get a String returned. Instead, valueOf() gets null from toString() and passes that back to print().
At that point, the code assumes that we have a reference to a String, not a null reference. After a few more method calls, BufferedWriter.write() calls getChars() on a null String reference and the NullPointerException is thrown.

I make two points:

1. How many test takers can work this out without the doc and maybe the source code?

2. Java considers null a universal type, so you can return it wherever any type of Object is expected. However, the Java library code does not always handle this, so you are risking a NullPointerException unless you have checked the API doc really carefully.
[ November 22, 2004: Message edited by: Mike Gershman ]
 
sanjeevmehra mehra
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Somebody mentioned that why I am relating it to toString() method. He is absolutely right, even my intention is not to relate it with any method. My intention was & is to know the basics of Java & my question is simple why it behaves differently when both conditions (methods returns) null. Right now we can go through Writer class or any other class and try to figure out the reason but should not it behave same way? :roll:
Sorry, if "I have missed any important point & I am wrong".




Output
inside toString
null
inside toString
NullPointerException
[ November 23, 2004: Message edited by: sanjeevmehra mehra ]
 
prajkta patil
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
public String toString()
{
if(i == 0) return "null";
else return "" + i;
}


above code gives o/p:
null
2

remember that return type of toString() is string.
 
prajkta patil
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
sanjeev,
i think so when u calls (new test().toString()) then compiler converts the output of toString() method of test class again into string therefore it converts null into "null".
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic