How to verify call by value of Java? - java

I read that Java does everything by call by value. I was wondering how to verify this fact? As far as I understand, in case of objects(not primitives) functions get its own copy of reference but points to same object. In that case, reference of that object in callee function and caller function should be different? How can I verify that? In other words, how to print the reference of the object.
System.out.println(object); //does this print reference i.e text following #
EDIT:
I understand that modifying object in callee function does change the value in caller function. I am interested in how to print the references of objects as in what property can I print on console that clearly shows me 2 different reference.

Java passes references by value. This means you'll get a copy of the reference, so once you dereference that you'll get to the same object in the heap as with the original reference.
But if Java was pass by reference:
public static void nullify(Object obj) {
obj = null;
}
public static void main(...) {
String x = "Hello";
nullify(x);
System.out.println(x);
}
The call to S.o.p. would print null if Java was pass by reference. But it isn't, so x is unchanged and you'll get Hello.

Assuming Class A property aa
A a= new A();
a.aa = 1;
// print a.aa here should be 1
method(a);
// here a.aa should be 2
Void method(A a) {
a.aa =2;
a = new A();
a.aa = 3;
}
So this shows reference was passed as value. When you change the object in the method it does not change the reference of caller.

I think the String Object#1ed3af is composed of the class name of your object and it's hashcode, separated by a #. This is a unique string, identifying it.
Read this topic to get a full explanation !

Related

Confusion on how Java StringBuffer works?

I'm working on an assignment right now, and am confused by this. The code given is simple:
public class Variables{
public static void main(String[ ] args){
StringBuffer b = "ghi";
f(b);
System.out.println(b):
}
public static void f(StringBuffer p){
p.concat("jkl");
}
}
The question simply asks what the output of the print statement will be. My first thought was simply "ghi", but this was incorrect. If the method f is taking b as a parameter and setting it to p, then how does .concat() modify b? I've read through the StringBuffer documentation and dont understand why this wouldn't end up with b equaling "ghi" while p is "ghijkl".
Basically, how is the .concat() method called on p also modifying b?
First, you need to create a StringBuffer correctly.
StringBuffer foo = new StringBuffer("some string");
You passed an object to a function. Java passes objects as references (the references themselves of course are passed by value). See: Is Java "pass-by-reference" or "pass-by-value"?
Since you have a reference to a StringBuffer and not a copy of it, you are actually modifying the same object as you would as if you were in main.
This is the difference between parsing by reference and parsing by value.
When you create a method taking a primitive, for example, it undergoes what is called parsing by value. The JVM pretty much creates a copy of the value and that is what you get in the method.
int j = 0;
foo(k);
System.out.println(j); //Will still be 0.
public static void foo(int i) {
//i is not j (what you called the method with), it is a copy of it that is only valid within this method
i++;
}
Now when you call the method with an object such as a StringBuffer you are parsing by reference. This means that you are not parsing the value of the StringBuffer(not parsing a StringBuffer` with "ghi" as its contents), but you are rather parsing a pointer to it. Using this pointer you can still operate on the original object within other methods and bodies of code.

Why do they call it pass by value in Java? [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
Ok, so I am a relatively new programmer. I have read over and over about passing variables. From what I have read here is what I've come to understand: In Java, when you pass a variable to a method (be it primitive or Object) you are ALWAYS passing by value. But what you are REALLY doing is passing a copy of the reference to an object or variable in memory.
So why do they call it pass by value? It seems to me you are passing by reference. Also, in C when you pass a pointer to a function, aren't you passing the address of a variable in memory? Yet it is called pass by value. What am I overlooking? Can someone please explain and clarify why I this? I know how to pass variables and such and I have read several SO posts on this but I am not fully satisfied yet. Consider an example:
static void setNameStatic(Dog d, String name) {
d.name = name;
}
public static void main (String args[]) {
Dog d = new Dog("dog1");
System.out.println( d.getName() );
setNameStatic( d, "dog2" );
System.out.println( d.getName() );
}
Won't this output: dog1 and dog2. So aren't you going to where the reference is referring to and changing data around? What exactly does the value have to do with here? Any helpful comments are appreciated. And yes, I know it is pass by value, but why isn't it called "pass by sending copy of reference" lol?
Update: Thanks to everyone that gave a helpful answer. I know this was marked duplicate, and sorry about that. I am satisfied with the answers now.
Your memory looks like this at the moment of:
Dog d = new Dog("dog1");
Stack (with local vars) Heap
+-----------+ points to
| Dog d | ---------------> real dog object
+-----------+
| ... |
+-----------+
| ... |
+-----------+
And then, when you pass in a reference to a method, it looks something like this (where the Dog dog2 is the method argument):
Stack (with local vars) Heap
+-----------+
| Dog d | ---------------> real dog object
+-----------+ ^
| ... | |
+-----------+ |
| Dog d2 |------------------------------
+-----------+
So, the reference is passed by value. It points to the same object but it is the new reference!
Meaning, if you would try something like this:
public static void main(String ... args) {
Dog d= new Dog("dog1");
setNameStatic(d, "dog2");
System.out.println(d); // Still prints dog1 !!!
}
static void setNameStatic(Dog d2, String name) {
d2= new Dog(name);
}
Because the new (copied) reference now points to the new object on heap and the original object has not changed.
Because the value of any variable of reference type is its address in memory.
Because the value of any variable of primitive type is its value itself.
So you always pass values of variables.
Every variable is passed by value. In the instance of primatives, we have the naive case - the values are passed into the function.
In the instance of Objects, we have a slightly more complicated although analogous paradigm - the references to the objects are passed by value.
Note the subtle differences:
//This is essentially a no-op. The values are only local to the function
void swap(int a, int b){
int temp = a;
a = b;
b = temp;
}
//This is different. The references to a and b are passed by value so the values of a.x and b.x are actually swapped on return.
void swap(Point a, Point b){
int temp = a.x;
a.x = b.x;
b.x = temp;
}
Passing by value means that the value is transferred to method, i.e. yet another copy of the same value is created:
int i = 5; // one copy of 5
foo(i);
private void foo(int n) {
// here n is 5, however it is "another" 5
}
The evidence of passing by value is that you cannot change your i from within the method foo():
int i = 5; // one copy of 5
foo(i);
// i is still 5 here
private void foo(int n) {
n = 6;
// n is 6, however it is actual inside the method only.
}
The same is with objects, however in that case reference is passed by value.
Also, in C when you pass a pointer to a function, aren't you passing the address of a variable in memory? Yet it is called pass by value.
No it is not. When you pass a pointer to a value to a function in C, it is known as 'pass by reference'. The function can directly access & modify the original value because it has it's address. Pass by value is when you pass the value of objects instead of their locations or addresses. Look at the following examples.
int addOne(int x)
{
return x + 1;
}
void destructiveAddOne(int *x)
{
*x += 1;
}
int main(void)
{
int x = 5;
int y = 5;
// We pass the _value_ of x, ie, 5 to addOne, and store the result in z.
// The value of x will remain unchanged, ie, 5.
int z = addOne(x);
// We pass a REFERENCE to y, ie, it's address to destructiveAddOne()
// destructiveAddOne then modifies the value of y to be y + 1. The value of y
// has now CHANGED to 6. This is call by reference.
destructiveAddOne(&y);
return 0;
}
A variable holds the bits that tell the JVM how to get to the referenced Object in memory (Heap).
When passing arguments to a method you ARE NOT passing the reference variable, but a copy of the bits in the reference variable. Something like this: 3bad086a. 3bad086a represents a way to get to the passed object.
So you're just passing 3bad086a that it's the value of the reference.
You're passing the value of the reference and not the reference itself (and not the object).
This value is actually COPIED and given to the method.
Had that before:
Is Java "pass-by-reference" or "pass-by-value"?
It is a tricky thing to get your head round. I think of it as real numbers, albeit abstracted. Say your first dog, dog1, is created at memory location "100,000" (I know but bear with me). You pass the reference's value of 100,000 around to methods. Your method changes the name of the object living at 100,000.
If you pass your dog1 object into a method that does d = new Dog("dogXXX"), then it will work with a brand new object at (say) 200,000 leaving your dog1 at memory address 100,000 unchanged.
Apologies for the memory address abuse which will have experts spitting their coffee...
In java you're passing parameters by value to the methods, but the parameters are themselves ref type if the parameter is an object.
As a contrast in a programming language like C that passing by reference is allowed, if you print a reference you get something different from what you get when print it's value.
To insure that objects are reference types and compare them with primitives, Try this:
public class TestClass {
public static void main(String[] args) {
String s = new String("a");
String t = new String("a");
System.out.println(s==t);
char a = 'a';
char b = 'a';
System.out.println(a==b);
}
}
The result is :falsetrue
References in Java are passed by value of the reference.
When you pass reference as a method parameter copy is created and you operate on this copy.
To illustrate it have a look at this sample code:
final Person person = new Person();
person.setName("A");
changeName(person, "B");
System.out.println(person.getName());
Now if we have changeName implemented as this:
private static void changeName(Person person, String name) {
person.setName(name);
}
Then the result is B. It's because copy of the reference still points to the same object and there is possibility to modify it.
On the other hand if you change the changeName method to this:
private static void changeName(Person person, String name) {
person = new Person();
person.setName(name);
}
Then the result is A. It's because copy of the reference points to the new object, but original reference still points to the original object and it's value is not modified.
If Java would pass object references by reference than the result would be B, because it would operate on the original object.
When you pass an object as a parameter in Java, you actually pass a reference, and the reference is the value used in the stack. However, any assignment you make to this reference inside the method will not be observed by the caller, because you only change a copy of the reference. Same goes with primitive values as parameters.
In other languages (like C++), you have the option to pass by reference, allowing you to change the reference itself from within a method. In Java, for example, you can't implement a swap method that takes two parameters and swaps them. In C++ it's possible.

Advance for reference variables?

I am trying to understand the difference between Object with primitive variables when using them as parameters in a method.
There are some examples using reference variables:
public class Test1 {
public static void main(String[] args) {
int[] value = {1};
modify(value);
System.out.println(value[0]);
}
public static void modify(int[] v) {
v[0] = 5;
}
}
result: 5
public class Test2 {
public static void main(String agrs[]) {
Integer j = new Integer(1);
refer(j);
System.out.println(j.intValue());
}
public static void refer(Integer i) {
i = new Integer(2);
System.out.println(i.intValue());
}
}
result: 2 | 1
So what is different in here?
In java array is primitive type.and Integer is Object type.
For primitives it is pass by value the actual value (e.g. 3)
For Objects you pass by value the reference to the object.
In first example,
you are changing value in array.
while in other example ,
you are changing reference of i to other memory location where object value is 2.
when returning back to main function, as you are not returning value. its reference scope limited to "refer" method only.
Recall that the array references are passed by value. The array itself is an object, and that's not passed at all (That means that if you pass an array as an argument, your'e actually passing its memory address location).
In modify() method, you're assigning 5 to the first place in the array, hence, changing the array's value. So when you print the result, you get: 5 because the value has been changed.
In the second case, you're creating a new Object of type Integer locally. i will have the same value when you exit the method refer(). Inside it you print 2, then you print i, which is 1 and hence change doesn't reflect.
v[0] = 5, is like saying Get 0th element of current v's reference and make it 5.
i = new Integer(2), is like saying change i to 2's Integer object reference
In one case you are changing the internal values via the reference and in latter you are changing the reference itself.
The difference here is that they are different.
In your first example you are passing the argument to another method, which is modifying one of its elements, which is visible at the caller. In the second case you are assigning the variable to a new value, which isn't visible at the caller, because Java has pass-by-value semantics.
NB 'Primary variable' has no meaning in Java.
I don't know what the word 'advance' in your title has to do with anything.

Why is an ArrayList parameter modified, but not a String parameter? [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 9 years ago.
public class StackOverFlow {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("A");
al.add("B");
markAsNull(al);
System.out.println("ArrayList elements are "+al);
String str = "Hello";
markStringAsNull(str);
System.out.println("str "+ str);
}
private static void markAsNull(ArrayList<String> str){
str.add("C");
str= null;
}
private static void markStringAsNull(String str){
str = str + "Append me";
str = null;
}
}
This outputs:
ArrayList elements are [A, B, C]
str Hello
In the case of ArrayList, the added elements are getting retrieved.
In case of String the method call has no effect on the String being passed. What exactly is the JVM doing? Can anyone explain in detail?
In the case of Arraylist string objects the added elements are getting retrived. In case of String the method call has no effect on the String being passed.
It happens cause Java is Pass-by-Value and Strings are immutable
When you call
markAsNull(ArrayList<String> str)
The a new reference by name str is created for the same ArrayList pointed by al. When you add an element on str it gets added to same object. Later you put str to null but the object has the new values added and is pointed by a1.
When you call
markStringAsNull(String str)
{
str = str + "Append me";
// ...
}
The line str = str + "Append me"; creates a new String object by appending the given string and assignes it to str. but again it is just reference to actual string which now pointing to newly created string. (due to immutablity) and the original string is not changed.
The markXAsNull methods are setting the local references to be null. This has no effect on the actual value stored at that location. The main method still has its own references to the values, and can call println using those.
Also, when doing the string concatenation, toString() is being called on the Object, and that is why the ArrayList is outputted as a list of its values in brackets.
From the Book: SCJP - Sun Certified Programmer for Java 6 Study Guide (Katty Sierra - Bert Bates) Chapter 3 Objective 7.3 - Passing Variables Into Methods
Java is actually pass-by-value for all variables running within a single
VM. Pass-by-value means pass-by-variable-value. And that means, pass-by-copy-ofthe-
variable!
The bottom line on pass-by-value: the called method can't change the caller's
variable, although for object reference variables, the called method can change the
object the variable referred to. What's the difference between changing the variable
and changing the object? For object references, it means the called method can't
reassign the caller's original reference variable and make it refer to a different object,
or null. For example, in the following code fragment,
void bar() {
Foo f = new Foo();
doStuff(f);
}
void doStuff(Foo g) {
g.setName("Boo");
g = new Foo();
}
reassigning g does not reassign f! At the end of the bar() method, two Foo objects
have been created, one referenced by the local variable f and one referenced by
the local (argument) variable g. Because the doStuff() method has a copy of the
reference variable, it has a way to get to the original Foo object, for instance to call
the setName() method. But, the doStuff() method does not have a way to get to
the f reference variable. So doStuff() can change values within the object f refers
to, but doStuff() can't change the actual contents (bit pattern) of f. In other
words, doStuff() can change the state of the object that f refers to, but it can't
make f refer to a different object!
Java follows passby value concept ( there is no pass by reference in java ) . So when you pass a string to the function it sends a "copy of reference" to that string to the function. So even if you set the variable to null in the function, when it returns to the caller it refers its original value only. That's why original string has no effect.
In case of Arraylist, copy of reference refers to the original Arraylist (which is also the same in case of string). But when you add something into ArrayList, it refers to the original object and so that you can see the effect. ( try in method arraylist=new ArrayList(), your original arraylist will remain as it is).
In case of string, when you do
str=str + "abc";
Java creates a new String object which will have reference to string "xyzabc" ( e.g. str="xyz") and "xyz" will be eligible for the garbage collection. But as "xyz" is still having an variable which refers to it it ( original string) will not be garbage collected. But as soon as the function call gets over "xyzabc" goes for garbage collection.
Summary of the discussion is, as long as an reference refers to the same object you can make changes in the function, but when you try to change the reference ( str=str+"abc") you are refering to the new object in the method so that your original object will remain as it is.
In Java, you may create one object, and referenced by multiple pointers. Calling a mutator method on any pointer will effectively modify the sole object, thus updating all other references.
But if you call variable assignment statements on a reference, only that pointer will be changed, since it doesn't do any object side work (this is the best I could explain...).
Passing an object to a parameter will effectively copy the reference, resulting in a single object, with two pointers - one global, and the other local.
One more point, since String is immutable, you'll actually get a new object, that is distinct from the original (from the fact that you have to say a = a + "a"), that's why it won't modify the original string.

Java. Argument does not change

static void f(String s)
{
s = "x";
}
public static void main(String[] args) {
String s = null;
f(s);
}
Why the value of s after calling f(s) is null instead of "x"?
Because s is a reference. You pass a copy of that reference to the method, and then modify that copy inside the method. The original doesn't change.
When passing an Object variable to a function in java, it is passed by reference. If you assign a new value to the object in the function, then you overwrite the passed in reference without modifying the value seen by any calling code which still holds the original reference.
However, if you do the following then the value will be updated:
public class StringRef
{
public String someString;
}
static void f(StringRef s)
{
s.someString = "x";
}
public static void main(String[] args)
{
StringRef ref = new StringRef;
ref.someString = s;
f(ref);
// someString will be "x" here.
}
Within the function f() the value will be "x". Outside of this function the value of s will be null. Reference data types (such as objects) are passed by value see here (read the section "Passing Reference Data Type Arguments")
Given that s is of type String, which is a reference type (not a primitive):
s = "x";
does not mean "transform the thing that s refers to into the value "x"". (In a language where null is a possibility, it can't really do that anyway, because there is no actual "thing that s refers to" to transform.)
It actually means "cause s to stop referring to the thing it currently refers to, and start referring to the value "x"".
The name s in f() is local to f(), so once the function returns, that name is irrelevant; the name s in main() is a different name, and is still a null reference.
The only thing that the parameter passing accomplishes is to cause s in f() to start out as null.
This explanation would actually go somewhat more smoothly if you hadn't used null :(
Actually you are not changing the value you are creating new one, it is totally different, If you change an attribute of the abject in the method then i will be changed in your references. But you are creating new object.

Categories

Resources