wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes can anyone explain this? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "can anyone explain this?" Watch "can anyone explain this?" New topic
Author

can anyone explain this?

Raji Addepalli
Ranch Hand

Joined: Dec 05, 2001
Posts: 50
What will be the result of attemping to compile and run the following class?
public class TestClass
{

public static void main(String args[])
{
int i = 1;
int[] iArr = {1};
incr(i);
incr(iArr);
System.out.println("i = " +i+ " iArr[0] = " + iArr [0]);
}
public static void incr(int n) {n++; }
public static void incr(int[] n){n [ 0 ]++; }
}
Ans:i = 1 iArr[0] = 2
i got the answer but can anyone explain this?
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Originally posted by Raji Addepalli:
What will be the result of attemping to compile and run the following class?
public class TestClass
{

public static void main(String args[])
{
int i = 1;
int[] iArr = {1};
incr(i);
incr(iArr);
System.out.println("i = " +i+ " iArr[0] = " + iArr [0]);
}
public static void incr(int n) {n++; }
public static void incr(int[] n){n [ 0 ]++; }
}
Ans:i = 1 iArr[0] = 2
i got the answer but can anyone explain this?

The key is to remember that arrays are Objects, therefore, and variables that contain an array really contain a reference to that array. Primitive variables, on the other hand, do not contain a reference to a primitive, but the primitive itself.
When you call incr(i), the compiler finds the version of the method incr which takes an int as a parameter and executes it. In this case, the first incr. The parameter n is a copy of i from the main method, rather than a reference to that variable. Therefore, any changes that happen to n within the method incr do not have any effect on the variable i within main. That's why i has not changed when you come back to main.
When you call incr(iArr), however, the compiler finds the version of the method incr which takes an int array as a parameter and executes it. In this case, the second incr. The parameter n is a reference to the variable defined in the main method. Therefore, any changes made to that variable within incr will effect the variable iArr within the main method. That's why the value of iArr[0] is changed when you get back to main.
I hope that makes sense. I sure wish someone would invent a forum where you could draw pictures of a stack trace so I could show you the activation records...that would make explaining this sort of thing much easier. :roll:
Best of luck,
Corey


SCJP Tipline, etc.
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Objects pass a copy to the method, so a change to the variable with will result to a change to iArr.

Rick was getting at the right thing above, but I'd be careful about the terminology he uses.
Update: I swear, there was a post from Rick here when I started this post (that's where my quote came from), but it's gone now. You can take the rest of this post for what it's worth, I guess.
In Java, all parameters are passed "by value." That means that a copy of whatever is in the variable that is passed is made and used by the called method.
The reason this makes a difference is that Java has 9 data types. The 8 primitives are stored directly in their variables and the other type, reference types (which really encapsulates any class), have a reference to them stored in their variables.
Looking back at the original code sample, you have two variables, i and iArr. The variable i contains the number 1 and the variable iArr doesn't really contain an array with one element in it. Rather, it contains a reference to that object. The array really exists somewhere in the heap.
Now let's look at what happens when you pass these two variables to a method.
First, when you pass i (which contains the number 1) to a method, a copy of that value is given to the method to use (because Java is pass by value). That method can now do whatever it wants to that new variable (in your example, the variable n) but, since n is an independent copy of i, i can never be modified by the method.
Now, let's look at what happens if you pass iArr (which contains a reference to an array). When you pass that to a method, you pass a copy of the reference contained within iArr to the method. Now, that method has its own independent copy of iArr called n. Just like the last example, the actual value of iArr can not be changed by modifying n. By that, I mean that iArr can not be set to a new value - it will always reference the same array on the heap. However, since n also references the same array, you can modify that array through n or iArr. So, even though iArr can not be modified by changing n, you can change the object that iArr references.
This can be difficult to understand at first. Just remember, Java is always pass by value. You have to be careful when you're talking about copies and references and parameters. It's very easy to confuse yourself and others.
Try the following code snippet and see if you can explain the result.

If you can explain why the above snippet does what it does, I'd say you have a good understanding of how Java passes variables as parameters.
Corey
[ January 14, 2002: Message edited by: Corey McGlone ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: can anyone explain this?