This week's giveaway is in the EJB and other Java EE Technologies forum.
We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line!
See this thread for details.
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes q from jiris.com Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "q from jiris.com" Watch "q from jiris.com" New topic
Author

q from jiris.com

JayaSiji Gopal
Ranch Hand

Joined: Sep 27, 2004
Posts: 303
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?


SCJP 1.4, SCWCD 1.4<br /> <br />Thanks in advance!<br />Jayashree.
Aneesha Singh
Ranch Hand

Joined: Jan 14, 2002
Posts: 47
Because, I think, in the line:

System.out.println(t1);

NULL is returned, throwing a runtime exception.
Premkumar Gopal
Greenhorn

Joined: Jun 12, 2004
Posts: 22
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 ).


SCJP(1.4), OCP(8i) DBA, Websphere Certified Associate Developer, Websphere Certified Solution Developer, Websphere Portal Application Developer
Premkumar Gopal
Greenhorn

Joined: Jun 12, 2004
Posts: 22
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

Joined: Oct 24, 2004
Posts: 22
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

Joined: Aug 21, 2004
Posts: 75


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 ]

thanks & regards,<br />Sanjeev.
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
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.


Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
Getting someone to think and try something out is much more useful than just telling them the answer.
Premkumar Gopal
Greenhorn

Joined: Jun 12, 2004
Posts: 22
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

Joined: Aug 21, 2004
Posts: 75
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

Joined: Mar 13, 2004
Posts: 1272
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.


Mike Gershman
SCJP 1.4, SCWCD in process
Hai Le
Greenhorn

Joined: Sep 22, 2004
Posts: 28
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


Step one step back to learn more thing..!!<br />Post to learn<br />learn from mistake<br />take whatever i understand...!!!<br /> <br />SCJP 1.4, Brainbench Java 1 & 2.<br />SCWCD 1.4 (preparing...!!)
Premkumar Gopal
Greenhorn

Joined: Jun 12, 2004
Posts: 22
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

Joined: Mar 13, 2004
Posts: 1272
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

Joined: Aug 27, 2004
Posts: 411
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.


Cheers,<br />Jay<br /> <br />(SCJP 1.4)<br />Heights of great men were not achieved in one day, they were toiling day and night while their companions slept.
Premkumar Gopal
Greenhorn

Joined: Jun 12, 2004
Posts: 22
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

Joined: Mar 13, 2004
Posts: 1272
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

Joined: Aug 21, 2004
Posts: 75
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

Joined: Nov 13, 2004
Posts: 49
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

Joined: Nov 13, 2004
Posts: 49
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".
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: q from jiris.com
 
Similar Threads
strange behaviour
Mock question
a highly recommended mock site: http://www.jiris.com/mock
Does the toString() method cannot return null?
a question