Today I saw a simple Java exam question about OOP
Before it, I knew stack and heap and the Java rule everything pass by value.
And value means the reference address stores in stack, not the object in heap.
Let have a look at this question:
What is output of this execute code?
class Person {
private String name;
public Person(String name) {this.name = name;}
public String toString() {return name;}
}
public class Tester {
public static Person checkPerson(Person p) {
if (p == null) {
p = new Person("Joe");
} else {
p = null;
}
return p;
}
public static void main(String[] args) {
Person p = null;
checkPerson(p);
System.out.print(p);
p = new Person("Mary");
checkPerson(p);
System.out.print(p);
}
}
Answer
A) Joenull
B) nullnull
C) Marynull
D) nullMary
The checkPeson() method logic
if (p == null) {
p = new Person("Joe");
} else {
p = null;
}
ah ha, the first print must be "Joe" cause we pass a null to it
right away select the Answer A - Joenull without any hesitate, but correct answer is D) nullMary
Wait, what? the first print is null.
But we have p = new Person("Joe") already in the method?
I start to doubt about did Java pass the reference of object to the method?
After some crazy search on internet, I finally understand why
By simple value in "everything pass by value" mean a copy of reference address value (not the real reference value)
The parameter I pass to the method is a clone of the real one, it's a local variable (a variable that's declared within the body of a method)
The real one still points to a null value, it got no effect after the method execute
That why we have correct answer nullMary
Oh what a shame, after 7 years in Software Development and 5 years with Java, Sometime thing I am a senior but everything collapse after this.
Couldn't believe I lacked this important point
My excuse
- I have learn many languages whenever my company have a new project (or when I land new job). Learn Java at university, first job with C#, then Ruby, VBA and final comeback with Java
- As a fullstack developer, I use 50% time working with Style and client events (javascript, JQuery)
- Lazy reading technical document, always prefer short explain and blog cause all I want is make code run as soon as possible
The way I am working is still good, customers love that problem solve quickly and I'm like a superstar in my team
But for me, it's time to slow down, learn the concept instead of google for code and use Trial-error method
Top comments (6)
Best thing my uni did was teach me c and c++ instead of java for this reason. If you have the time, working with manual memory allocation really clears these things up. After that, for most languages with a GC the rule is pass by value for primitives, and pass by reference for everything else.
You also notice that
p
is really a pointer, just dressed up. When you passp
tocheckPerson
you are passing the pointer by value. This means the data is copied when passed, and changes to it won't affect the original. I have a more detailed explanation below but this is the short version. Thanks for sharing! I know it's hard being wrong on the internet, especially when you're more experienced but stumbled into a knowledge gap.Long version:
So let's walk through it:
p
is created on the stack. It is of typeperson
but this is just java abstracting away what's really happening:p
is actually a pointer (a variable which contains an address in memory) to an object of typeperson
. Note that thenew
keyword is not used, and instead this pointer is set tonull
.checkPerson(p)
is called. Remember thatp
is really a pointer in the background. So its value is copied and given to the newp
insidecheckPerson
. Notice how we are just evaluatingp
, whatever is returned will just be ignored.checkPerson
notices thatp
is null, creates a new person, joe, on the heap, and sets p to joe's address. Remember that p as a pointer is really passed by value, so this is just a copy. The original p is still null. It then returns p. This doesn't come up often in java because usually your changing values or executing methods associated with p. When this happens you would follow p to the same object in heap that the calling function sees. However, in this case we are changing p, the pointer, itself.p = check person(p)
we would be in a very different universe.mary
and then run check person on it. Inside check person, p is set to null, but that doesn't matter as p is passed by value.Working with languages like c and c++, while certainly a pain at times, can really provide insight into how languages like java manage data in the background. If you have the time and are looking for an exercise, I suggest studying c data structures. Get to a point where you can implement a linked list without a reference source, without memorizing it either, and without memory leaks. Then do the same for c++ and you'll see how oop allows you to do data structures in a safer, more organised way. After that you can do the same in java, and you'll see how garbage collection prevents most memory leaks, and how it allows you to abstract away the idea of pointers without truly removing them. As a side project you can look at doing it again in c++ but using RAII (resource allocation is initialization) principals. Although that doesn't really relate to what's here, it's just a cool idea.
Hi @matthewsalerno
Thank you for your explanation, that's very clear to me
I had learn C in university too, but they didn't tell much more about pointer and datastruct, just teach you how to work with method, loop than do the final exam with something like print the fibonacci...
My country market will push you to learn language like Java and C# then find a outsource job that implement big system from Japanese, US and EU.
C just for the newbie to start learn programming (seem replace by python now a day)
Btw i have some Arduino for my personal project, and working with C++ in electricity domain kinda fun.
Thanks again for posting! I've been meaning to learn more about Java, I don't know much about it aside from things that translate easily from the c, c++, and python worlds. So this gave me a good opportunity to dig into it a bit more. I still need to learn more about how a normal java workflow operates.
And the Arduino is a lot of fun to work with. Definitely the most rewarding, and the most frustrating experiences I've had are with microcontrollers.
I was told to know nothing about Java when I used the word "pointer" to explain something like that.
Haha, tbf I don't really know anything about Java. I'm just translating it to a problem that's fairly common in C. Not sure what you would call it though. Perhaps "reference" is more appropriate?
I don't think there is a problem with the word pointer. Sorry, if that wasn't clear. I like your explanation, I'm just salty.
As far as I can see, reference is more common to use in Java, but from my view pointer isn't just a feature in a specific programming language, but a concept. So maybe if someone calls you stupid for using the word pointer, he isn't worth the explanation.