Win a copy of Java XML & JSON this week in the XML and Related Technologies forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Devaka Cooray
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Junilu Lacar
  • Paul Clapham
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • salvin francis
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Ganesh Patekar

String Object as pass by value  RSS feed

 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I have this lines of code and its output is somewhat confusing me with concepts of String immutability and object reference as pass by value.


In replaceString() method i reassign the substring value 'av' to str and it is printed same on the console.
But the answer printed on the console by the main method is 'java'.

I am aware that string is immutable and that is what is the correct behavior of this code. Also object reference is pass by value so str and  s1 has reference of the same string object.
I might have confused myself with these two concepts.
A nice clarification will be helpful.

Moreover, I am new to this forum and this is my first post so kindly consider any mistakes.

Thanks in advance!
 
Saloon Keeper
Posts: 9703
192
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to CodeRanch!

s1 is a variable that holds a reference to an object of type String. That object represents the string "java".

When you pass s1 to replaceString(), you pass the value of s1, which is a reference to an immutable object. After the call returns, s1 still holds the same reference to the same object, and since that object is immutable, the next println() statement will print "java".

So what happens inside replaceString()? It gets passed a reference to a String object, and it calls substring() on it. This call returns a different reference to a new String object. This reference, (which again, is a value) is assigned  to the variable s.

So inside the replaceString() method, the only thing you did was reassign the value of the s variable, so it now points to a different object. Since s is a local variable (Assuming you meant the method parameter to read s, not str), it doesn't affect anything outside the method.

All of this is different from passing by reference, in which you don't pass the value of a variable, but the variable itself. In that case, the local s variable would just be an alias for the s1 variable that you pass to the method, and any assignment that you make to the local variable will be reflected in the variable that you passed. Java does NOT support this feature. When you use a variable name in a method call, it will not pass the variable itself, it will pass a copy of the reference that the variable holds.

Most people are confused by these concepts because the C++ language used the phrase pass-by-reference when passing a variable to a method call, instead of the value of that variable. In Java, the term reference is used for something different completely, which in C++ is closer to a pointer.
 
Stephan van Hulst
Saloon Keeper
Posts: 9703
192
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A small remark on your code. Don't call new String() with another String as its argument, unless you are a very experienced Java programmer and know what you're doing and why, and NEVER call it on a String literal. Instead, use the literal directly:
 
Indivar Gajbhiye
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Stephen,

Thank you for the instant answer.
So I would just quickly summarize my understanding. Since the substring method internally returns a new object and str(typo in replaceString method) is a reference to that new object hence it has no updation on the initial object referenced in the main method. If instead of String it would have been any other immutable object, modifications in replaceString method would have reflected the changes in the original object as well.
 
Stephan van Hulst
Saloon Keeper
Posts: 9703
192
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Exactly. If String was mutable, and you mutate it, it would be visible in the main method. That's because even though you're not able to change the s1 variable (because you pass a copy of its value, which happens to be a reference), you're able to change the object that it refers to.

WARNING: In the discussion below there be DRAGONS. If you're not familiar with C++, ignore it.

Your application would be similar to the following in C++:

Here, it's obvious that s1 is a pointer to a string object with the value "java". When you pass s1 to replaceString(), the pointer value is passed, not the variable itself, nor the object itself. s->substr(1, 2) returns a new object, and then a new pointer is assigned to s. Neither the variable s1 is affected, nor the object that it points to.

Now, there are three ways that you can cause the main method to print "av":

  • Return the pointer to the new object, and reassign s1 in the main method. This is the normal way you would do it in Java with immutable types.
  • Pass the pointer value and change the object it points to. This is not possible in Java because String is immutable, but it's how it normally works in Java for mutable types.
  • Pass the variable itself, and change its value. This is not possible in Java because it doesn't support pass-by-reference. This is the normal way of doing it in C++.

  • And this is how all three of them look in C++:


     
    All of the world's problems can be solved in a garden - Geoff Lawton. Tiny ad:
    RavenDB is an Open Source NoSQL Database that’s fully transactional (ACID) across your database
    https://coderanch.com/t/704633/RavenDB-Open-Source-NoSQL-Database
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!