• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 637
  • Last Modified:

pass by value in java

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
gudii9
Asked:
gudii9
  • 5
  • 5
  • 2
  • +3
2 Solutions
 
CPColinSenior Java ArchitectCommented:
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
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
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
 
dpearsonCommented:
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
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
CPColinSenior Java ArchitectCommented:
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
 
Mahesh BhutkarCommented:
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
 
Sharon SethCommented:
0
 
gudii9Author Commented:
" 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
 
dpearsonCommented:
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
 
gudii9Author Commented:
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
 
dpearsonCommented:
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
 
gudii9Author Commented:
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
 
dpearsonCommented:
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
 
gudii9Author Commented:
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
 
dpearsonCommented:
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
 
gudii9Author Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 5
  • 5
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now