Solved

pass by value in java

Posted on 2014-02-04
15
586 Views
Last Modified: 2014-02-22
Hi,

i was working on this example

http://www.avajava.com/tutorials/lessons/do-java-methods-use-pass-by-reference-or-pass-by-value.html?page=2


I have not understood the output clearly.
a (in main) is: 1
a (in doSomething) is: 2
a (in main) is: 1

myTest's x (in main) is: 1
myTest's x (in doSomething) is: 2
myTest's x (in main) is: 2

s (in main) is: str1
s (in doSomething) is: str2
s (in main) is: str1

myTest2's x (in main) is: java.lang.NullPointerException

myTest3's x (in main) is: 1
myTest3's x (in doSomethingAndNull) is: 3
myTest3's x (in main) is: 3



I wonder how i got as below for the String argument passing call in the method.

s (in main) is: str1
s (in doSomething) is: str2
s (in main) is: str1


I thought it supposed to be

s (in main) is: str1
s (in doSomething) is: str2
s (in main) is: str2

similar to object references(since String is also an object)

please advise
Any links resources ideas highly appreciated. Thanks in advance
0
Comment
Question by:gudii9
  • 5
  • 5
  • 2
  • +3
15 Comments
 
LVL 14

Expert Comment

by:CPColin
ID: 39833554
I started typing up an explanation for what happened, then noticed that the tutorial you linked already details what's going on. Is there a specific part of that explanation that you're having trouble with?
0
 
LVL 142

Assisted Solution

by:Guy Hengel [angelIII / a3]
Guy Hengel [angelIII / a3] earned 100 total points
ID: 39833590
in java, "everything" is an object, so also a string

so, if you pass a value (object) byval, you are implicitly creating a copy of the object.

hence, you will modify (in doSomething) the value on the copy of the object, not of the object itself.
0
 
LVL 26

Expert Comment

by:dpearson
ID: 39833599
The first example in the code for an object sets a value like this:

myTest.setX(2);

This doesn't change what "myTest" is referring to.  It's changing the value *inside* the object it is pointing to.

myTest = anotherObject ; // This would change what myTest is pointing to

Now compare that to the string situation:

s = "str2";     // This changes what "s" refers to, not the value stored *inside* the String object.  See how this looks more like the "myTest = anotherObject" case?

If you wanted to get the same sort of behavior as for the object example, you'd need a class like this:

class MyStringContainer {
    private String x ;
    public void setX(String value) { x = value ; }
    public String getX() { return x ; }
}

Then:

      public static void main(String[] args) throws IOException {
                MyStringContainer myTest = new MyStringContainer() ;
            System.out.println("\nmyTest's x (in main) is: " + myTest.getX());
            doSomething(myTest);
            System.out.println("myTest's x (in main) is: " + myTest.getX());
      }

      public static void doSomething(MyStringContainer myTest) {
            myTest.setX("new string");
            System.out.println("myTest's x (in doSomething) is: " + myTest.getX());
      }

Now the string will change value - because

myTest.setX("new string");

is changing the value inside the "myTest" object, rather than changing what myTest refers to.

Making better sense yet?

Doug
0
 
LVL 14

Expert Comment

by:CPColin
ID: 39833600
Guy,

The value that is copied is the address of the object, not the object itself. In this case, the doSomething() method assigns a new address to the object reference that was passed in, without changing the original object at all.
0
 
LVL 6

Expert Comment

by:Mahesh Bhutkar
ID: 39834908
Java Supports Pass by value,
For Primitive data type it would be Pass by value...
For Object, it would be Pass by value of reference...
0
 
LVL 12

Expert Comment

by:Sharon Seth
ID: 39835162
0
 
LVL 7

Author Comment

by:gudii9
ID: 39843025
" When we do an assignment operator with a String reference, we are actually creating a new String object for the reference to point to. Strings is Java are "immutable", which means that the value of a String object can't change after the String has been created. So, the call to 's = "str2";' actually creates a new String object for the String reference 's' in the method to point to. So, the 's' reference in the doSomething() method points to a new String object with the value "str2", but the 's' reference in the main() method still points to the String object with value "str1".

Makes more sense. But how same 's' is assigned to "str1" in main() as below
public class Test {

      public static void main(String[] args) throws IOException {
...
            String s = "str1";
            System.out.println("\ns (in main) is: " + s);
            doSomething(s);
            System.out.println("s (in main) is: " + s);
...
      }

 also s is assigned to "str2" inside other method as below
public static void doSomething(String s) {
            s = "str2";
            System.out.println("s (in doSomething) is: " + s);


please advise
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 26

Expert Comment

by:dpearson
ID: 39843060
String s is a reference to an object (a pointer).

So you are free to move it to point to any object/String that you like.  But changing your reference is NOT the same as changing the object.

String s = "hello" ;
String t = s ; // t points to "hello" as well.

Now:
s = "goodbye" ;  // Doesn't affect the string "hello".  Just points to "goodbye" now.

t is still pointing to "hello" (because we didn't change the object at all).
s is now pointing to "goodbye"

Any good?

Doug
0
 
LVL 7

Author Comment

by:gudii9
ID: 39857263
but changing where the reference in the method points to doesn't change where the original reference outside of the method points to."


t is still pointing to "hello" (because we didn't change the object at all).
s is now pointing to "goodbye"


so s is pointing to goodbye not hello in same logic s  also should point to str2 not str1 after call to doSomething() method call?

so s can simulatneously refer to str1 in main method and to str2 inside the doSomething() method.



May be some pictorial representation helps a lot. Please advise
0
 
LVL 26

Expert Comment

by:dpearson
ID: 39857376
so s can simulatneously refer to str1 in main method and to str2 inside the doSomething() method.

Yes that's right because that's actually two different variables.  Calling them both 's' is actually just confusing the situation.

The original code was:
public static void main(String[] args) throws IOException {
		String s = "str1";
		doSomething(s);
	}

	public static void doSomething(String s) {
		s = "str2";
	}

Open in new window


This code is actually *identical* to this code:
public static void main(String[] args) throws IOException {
		String s = "str1";
		doSomething(s);
	}

	public static void doSomething(String another) {
		another = "str2";
	}

Open in new window


which maybe makes it more obvious that the "String s" in main is not the same as the "String another" in doSomething() and that setting

another = "str2"

has no effect on s.

Doug
0
 
LVL 7

Author Comment

by:gudii9
ID: 39867863
I see the example as below

import java.io.IOException;

public class Test {

	public static void main(String[] args) throws IOException {

		int a = 1;
		System.out.println("a (in main) is: " + a);
		doSomething(a);
		System.out.println("a (in main) is: " + a);

		MyTest myTest = new MyTest();
		System.out.println("\nmyTest's x (in main) is: " + myTest.getX());
		doSomething(myTest);
		System.out.println("myTest's x (in main) is: " + myTest.getX());

		String s = "str1";
		System.out.println("\ns (in main) is: " + s);
		doSomething(s);
		System.out.println("s (in main) is: " + s);

		try {
			MyTest myTest2 = new MyTest();
			myTest2 = null;
			System.out.print("\nmyTest2's x (in main) is: ");
			System.out.println(myTest2.getX());
		} catch (RuntimeException e) {
			System.out.println(e);
		}

		MyTest myTest3 = new MyTest();
		System.out.println("\nmyTest3's x (in main) is: " + myTest3.getX());
		doSomethingAndNull(myTest3);
		System.out.println("myTest3's x (in main) is: " + myTest3.getX());

	}

	public static void doSomething(int a) {
		a = 2;
		System.out.println("a (in doSomething) is: " + a);
	}

	public static void doSomething(MyTest myTest) {
		myTest.setX(2);
		System.out.println("myTest's x (in doSomething) is: " + myTest.getX());
	}

	public static void doSomething(String another) {
		another = "str2";
		System.out.println("s (in doSomething) is: " + another);
	}

	public static void doSomethingAndNull(MyTest myTest3) {
		myTest3.setX(3);
		System.out.println("myTest3's x (in doSomethingAndNull) is: " + myTest3.getX());
		myTest3 = null;
	}

}

Open in new window


I got output as below

a (in main) is: 1
a (in doSomething) is: 2
a (in main) is: 1

myTest's x (in main) is: 1
myTest's x (in doSomething) is: 2
myTest's x (in main) is: 2

s (in main) is: str1
s (in doSomething) is: str2
s (in main) is: str1

myTest2's x (in main) is: java.lang.NullPointerException

myTest3's x (in main) is: 1
myTest3's x (in doSomethingAndNull) is: 3
myTest3's x (in main) is: 3



which makes more sense as it is new string.

Also



class MyStringContainer {
    private String x ;
    public void setX(String value) { x = value ; }
    public String getX() { return x ; }




      public static void main(String[] args) {
                MyStringContainer myTest = new MyStringContainer() ;
            System.out.println("\nmyTest's x (in main) is: " + myTest.getX());
            doSomething(myTest);
            System.out.println("myTest's x (in main) is: " + myTest.getX());
      }

      public static void doSomething(MyStringContainer myTest) {
            myTest.setX("new string");
            System.out.println("myTest's x (in doSomething) is: " + myTest.getX());
      }

}

Open in new window


When i run above code i get output

myTest's x (in main) is: null
myTest's x (in doSomething) is: new string
myTest's x (in main) is: new string



I see String value is getting effected in above example you mentioned.


more obvious that the "String s" in main is not the same as the "String another" in doSomething() and that setting


I wonder why java has string method calling mechanism similar to Object when both concepts are 360 degrees apart.It is confusing. What are the practical uses of pass by value and pass by reference. I do not know any other programming language. I wonder what is big deal about this concept in practical stand point. please advise
0
 
LVL 26

Expert Comment

by:dpearson
ID: 39868434
What are the practical uses of pass by value and pass by reference. I do not know any other programming language. I wonder what is big deal about this concept in practical stand point

Almost all modern languages use pass by value.  Pass by reference is generally a lot more complicated and error prone.  C++ supports it but only if you deliberately ask for it (in the way you pass the parameters).

Pass by reference is something of a throw-back to the days when memory was scarce and CPUs not very powerful.  You could make some algorithms more efficient by using pass by reference.  But today we know that CPU cycles aren't usually the big challenge in developing software - it's making sure that the program works correctly that's the big challenge.  And pass by value makes it easier to have a working program, so it's preferred i modern languages.  (If you don't understand why - just take that on trust).

As long as you fully understand how pass by value works, you should be fine to ignore the concept of pass by reference.  You could program for many years and never need to understand the distinction.

Doug
0
 
LVL 7

Author Comment

by:gudii9
ID: 39880102
primitive and strings are clear(which are behaving same by not changing values after doSomething method call in main). But with objects I have not understood below statement in the link clearly (by changing values of myTest3.getX after doSomething method call in main))

Our output is shown here. We can see that we changed the value of the myTest object's x field. In proper terms, I guess we should say that we changed the x field of the object that the myTest reference in our main method points to.

myTest's x (in main) is: 1
myTest's x (in doSomething) is: 2
myTest's x (in main) is: 2


what it specifically mean
say that we changed the x field of the object that the myTest reference in our main method points to

May be a picture is helpful to visualise x field of object (myTest) in main method of other java class(Test.java)
0
 
LVL 26

Accepted Solution

by:
dpearson earned 400 total points
ID: 39880138
Is this clear:

MyTest mytest = new MyTest() ;
System.println(mytest.getX()) ; // Prints 1

myTest.setX(2) ;
System.println(mytest.getX()) ; // Prints 2

Then how about this?
MyTest mytest = new MyTest() ;
MyTest myOtherReference = mytest ;
System.println(mytest.getX()) ; // Prints 1
System.println(myOtherReference.getX()) ; // Prints 1

myOtherReference.setX(2) ;
System.println(myOtherReference.getX()) ; // Prints 2
System.println(mytest.getX()) ; // Prints 2 <-- Make sure you understand this


OK then when we use a method, this is *exactly* the same as what's happening with "myOtherReference".

MyTest mytest = new MyTest() ;
System.println(mytest.getX()) ; // Prints 1

doSomething(mytest) ;
System.println(mytest.getX()) ; // Prints 2 <-- Same reason that it printed 2 above

public void doSomething(MyTest myOtherReference) {
   // myOtherReference = myTest at this point, just like in my earlier code
   myOtherReference.setX(2) ;
}

Does that clear up the last confusion?

Doug
0
 
LVL 7

Author Comment

by:gudii9
ID: 39880158
myOtherReference.setX(2) ;
System.println(myOtherReference.getX()) ; // Prints 2
System.println(mytest.getX()) ; // Prints 2 <-- Make sure you understand this

that is true since both references point to same object.

Finally all makes sense. thank you very much.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now