Changes to parameters passed to a static function in java [duplicate] - java

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
class Util{
public static void F(Point p, Point q) {
p.x = 42;
p = q;
}
}
…
Point a = new Point(10,20);
Point b = new Point(30,40);
Util.F(a,b);
System.out.println(a.x + " " + b.x);
if someone can please explain me why the output is 42 30
thank in advance!

References are passed by values: http://javadude.com/articles/passbyvalue.htm
Let explain by a metaphore:
Suppose a red button.
When I click on the red button, a ball appears.
Now, in order to have quickly more balls, a new button is assigned the same function: the same ball appears when clicked.
Then, a person comes and alters this new button, to make an other ball appear!
What do you expect about the first button? To make appear the original one or the new one?
The original one of course! Since, although buttons pointed to the same ball, they are totally independent, explaining why change applying on the second button does not alter the objective of the first one.
Only if the second button MUTATED the first ball (without changing it!), for instance painting it in blue instead of red, then yes, the first button would point to the same ball blue, since it's..the same!
Replace original button by your a or b references and the ball by the x value of the created Point.
p.x = 42 is the assignment of the second ball.
p method parameter is the second button (since passed by value/copy).
Don't forget: MUTATIONS (p.x = 42 for instance) are visible to the caller environment but not the case of REPLACEMENTS (assignment)
I hope you understand now why the output is 42 30 and not 30 30 as you surely expected ;)

when you do p = q that does not change the value of Point a, it just change the reference of the temporary variable p, to be q.
but p.x=42 references to a value inside p, so that actually change it

p and q are value copies of references. Within F, assigning p = q just changes what p is pointing to, not the actual object itself, or any value in the caller.
p.x = 42 changes the field x to have the value 42 in the object referenced by p.
Putting it all together, a will have its x field changed by Util.F, but b is not changed in any way.

Method F changes value of field x in object passed as 1st argument to 42, while it doesn't change any state of fields in object passed as 2nd argument.
So, what you have done: you create object a, it doesn't matter what values you have passed inside its constructor: method F changed a.x to 42 <- this is the first part of your output.
Also you have created object b with x state equals to 30. Method F didn't change its values, so this is the second part of your output.
What about string code line p = q - it doesn't do anything worth. It just changes reference for variable p to be reference to object on which references variable q. It doesn't change object's state itself.

Related

Java Multithreading Value Corruption

Asking a question from https://www.baeldung.com/java-thread-safety.
Code given is
public class MathUtils {
public static BigInteger factorial(int number) {
BigInteger f = new BigInteger("1");
for (int i = 2; i <= number; i++) {
f = f.multiply(BigInteger.valueOf(i));
}
return f;
}
}
The above linked website says that it is stateless and multiple threads can run this method at same time and get proper results. My question is: doesn't the value of number variable get corrupted, when many threads call this?
The specific mechanism you need to be aware of is the stack.
Each thread gets its own stack. The stack is a traditional last-in-first-out setup: You can 'push' things on it, and you can 'pop' things off it, which will retrieve and remove the most recently pushed thing.
Each thread has its own unique stack. The stack is used for both local variables and execution pointers. Imagine this code:
public static void main(String[] args) {
a(5);
System.out.println("Done");
}
public static void a(int x) {
b();
System.out.println("In a: " + a);
}
public static void b() {}
Now imagine you're a CPU. You are just pointed at an instruction and are supposed to run it. You don't know java and you don't know what a loop is. You just know about basic instructions, including 'GO TO'. But that's all you have.
How would you know where to go back to once b() is done running? How would you know that you have to jump back to the midpoint of the a method and continue at System.out.println("In a")?
The stack is the answer. When executing b(), what happens under the hood is:
PUSH [position in this method we're at right now]
GOTO [position of the start of the b method]
And the b() method ends in an instruction that means: POP a number off of the stack and then GOTO that number.
Local variable are ALSO stored on the stack. So, the instruction set of all this is essentially:
1 PUSH 4 // position to return back to once a is done
2 PUSH 5 // from a(5)
3 GOTO 8 // a method
4 PUSH 7
5 CREATE_OBJECT "Done" // pushes pos of new object on stack
6 GOTO [position of System.out.println]
7 EXIT_APPLICATION
8 PUSH 10 // position to return back to
9 GOTO 16 // b() method
10 CREATE_OBJECT "In a: " // pushes pos of new object on stack
11 FLIP // flip the top two stack entries
12 CONCAT_STRINGS
13 PUSH 15 // position to return back to
14 GOTO [position of System.out.println]
15 RET // pop number and go to it
16 RET
(This is HIGHLY oversimplified; CPUs and bytecode are way more complicated than this, but it gets the point across, hopefully!)
The stack as a concept explains how java works:
Methods are 're-entrant', and each local variable and parameter is a unique copy every time the method runs. That's because these are represented by things on the stack, and you can of course just keep adding things to it. In that sense the stack is a relative thing: "System.out.println(b)", if b is a local var or parameter, is like an instruction to read a line in a book 'two lines above where you are currently reading' (that'll be a new line as long as you keep reading), vs an instruction to read 'line 8 in this book', which is the same line every time.
Java is pass-by-value, which means everything you get is a copy:
int x = 5;
add1(x);
System.out.println(x);
public void add1(int x) {
x = x + 1;
}
the above prints 5 and not 6, because add1(x) is shorthand for:
PUSH current_value_of_whatever_the_x_variable_holds
CALL add1
and add1 is going to operate on that pushed value, and not on your x variable. It gets a little convoluted when we involve objects (because objects in java are represented by their reference: A pointer. Imagine an object is a house, and a reference is more like an address. I can have an address to my house, and then hand you a copy of that address on a piece of paper. You can take a pen and change that paper all you like, it does not affect either my address book or my house. But if you drive over to the house and toss a brick through the window, even though I handed you a copy of a page of my address book, that's still my window. So:
List<String> list = new ArrayList<String>();
list.add("Hello");
add1(list);
System.out.println(list);
public void add1(List<String> list) {
list.add("World!");
}
This would print Hello, World!. Because . is the java equivalent of 'drive over to the house that address list is pointing to. Had I written list = List.of("Hello", "World!"), nothing would appear to happen, as = is java equivalent of: Wipe out the address card and write a new address on it. Which doesn't affect my house nor my address book.
Multiple threads can indeed call MathUtils.factorial() safely.
Each activation of factorial will have its own copy of f, accessible to it alone. That is the meaning of a "local variable".
The argument number is not modified, and acts like a local variable of `factorial' in any case.
As to your question in the comment. No, there's one copy of the code - no need to have more that one. But each thread has its own execution of the code, so if it helps to think of that as a 'separate copy', not much conceptual harm is done.
Whenever any thread (apart from main thread) starts execution of "factorial(int number)" method, that thread saves a copy of "number" into it's own stack as local variable and hence there is no chance to change the value of "number" by any other thread.
However, if "number" value is coming from any shared object(shared by multiple threads), and if it is copied by multiple threads into stack & after that value got changed by some thread(s), then in this case there could be a chance of data inconsistency (check 'volatile').

Java Objects and Pointers from C++ Perspective [duplicate]

This question already has answers here:
Does Java have pointers?
(12 answers)
Closed 8 years ago.
I recently read this post: Is Java "pass-by-reference" or "pass-by-value"?
The first answer was far too terse and specific to give me a firm understanding, and everyone else created 15 page essays explaining what should be a simple topic. Are the following rules correct (which are pretty simple if true):
1.) Named things associated with a type that aren't primitives ("objects references" in Java talk) are pointers in C++.
2.) . on a Java pointer is the same as using -> on a C++ pointer.
3.) = on a Java pointer is the same as using = on a C++ pointer.
4.) All functions pass by value (and hence pass Java pointers by value).
(This ignores memory management differences like the fact that = on a Java pointer is fine whereas = on a C++ pointer means you might need to worry about memory management)
The most confusing element to the puzzle is that no one I have seen has conveyed this set of rules/understanding of what Java is doing in clear English (opting instead for 15 pages and diagrams). The second most confusing element is that Java uses the word "reference" in a way that is different from C++. If you want an analogy between what Java is doing in terms of C++, pointers and the rules I created are the simplest terms to digest Java's behavior.
Point 1 is correct.
Object o = new Object();
Variable o is storing a pointer to where the object is in memory.
Point 2 is also correct.
Object o = new Object();
o.hashCode();
This is calling the method hashCode of the object stored in o.
Point 3, correct again.
Dog d = new Dog();
Dog d2 = new Dog();
System.out.println(d == d2);//This will print false
d2 = d;
System.out.println(d == d2);//This will print true
In the first output d does not equal d2 because the pointers to the objects are different. In the second output d does equal d2 because they both are pointing to the same location.
Point 4 is technically correct.
Primitives are passed by value.
A
When passing objects to a function it is passing a copy of the pointer to the object and not a copy to the object itself. The pointer to the object is being passed by value to the function. Hopefully this snippet can help explain it.
public void example(int i, Object o) {}
public static void main(String[] args) {
Object o = new Object();
example(3, o);//This is passing the number 3 to the function. It also passes by vlue a pointer to where object o is stored in memory.
}

java - call by reference ambiguity [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
I'm familiar with Call by reference concept in java but after seeing this code I'm confused
public class App
{
public static void main( String[] args )
{
Test t1 = new Test(1);
Test t2 = new Test(8);
App.doSomething(t1, t2);
System.out.print(t1.a);
System.out.print(t2.a);
}
public static void doSomething(Test t1, Test t2){
System.out.print(t1.a++);
System.out.print(t2.a++);
t1 = new Test(999);
t2 = new Test(888);
}
}
Prints:
1
8
2
9
Why does'nt value of "t1.a" and "t1.b" in the main function change to 888 and 999?
Java does not have call by reference. All parameters are passed by value -- but in the case of a parameter that is an object, the "value" that is passed is a reference to the object.
As a result, if you use the local reference to that object within the method to modify the object, it will modify the same object. However, if you assign something to that local variable, then it no longer has a reference to the original object, and subsequent changes will not affect the original object.
Thats why you typically set your method arguments to final - to avoid this kind of confusion :) findbugs would actually produce a style warning about this effect
That's because in java arguments are always pass-by-value.
In your example you pass a reference to a object, however this reference is passed by value. In other words, new local variable t1 is created and initialized with the references to your object that has been passed in the argument. So when you assign new Test() to it, only the local variable references the new object.
In Java everything is pass by value. The scopes of the 2 t1's and t2's are different. One is in the scope of main() and the other is in the scope of doSomething(). So the reason it isn't changed to 888 or 999 is because those values don't exist once you leave doSomething().
Novices have a hard time with this, I'll try to explain in story form:
If I let you borrow my sticky note (with my name on the top) with an arrow that points to the red sofa, and you take my sticky note and erase my arrow and put on a new arrow to the green sofa. When you finish your shenanigans, I will have a sticky note with my name on it that points to the green sofa. My stickynote was changed.
If however, I let you borrow my sticky note with my name on it, which has an arrow that points to the red sofa, and you take my sticky note and set it to the side, and you make a new sticky note with your name on it, then you put an arrow on it pointing to the green sofa, and you finish your shenanigans, then my sticky note is unchanged with my name pointing to the red sofa. You created your sticky note that I can't reach.
When you crammed a new object into t1, you didn't destroy the old one because you do not have authorization to do so. You simply pushed it to the side, and created a new one, which nobody has access to except you.
This line:
t1 = new Test(999);
Does not erase the old t1. You simply make a new t1 that is only local to the method, which is garbage collected after the method ends. With this line, you didn't change the parameter passed in, you created a new variable with the same name.

Is it possible to swap two variables in Java? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to write swap method in Java?
Given two values x and y, I want to pass them into another function, swap their value and view the result. Is this possible in Java?
Not with primitive types (int, long, char, etc). Java passes stuff by value, which means the variable your function gets passed is a copy of the original, and any changes you make to the copy won't affect the original.
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
// a and b are copies of the original values.
// The changes we made here won't be visible to the caller.
}
Now, objects are a bit different, in that the "value" of an object variable is actually a reference to an object -- and copying the reference makes it point at the exact same object.
class IntHolder { public int value = 0; }
void swap(IntHolder a, IntHolder b)
{
// Although a and b are copies, they are copies *of a reference*.
// That means they point at the same object as in the caller,
// and changes made to the object will be visible in both places.
int temp = a.value;
a.value = b.value;
b.value = temp;
}
Limitation being, you still can't modify the values of a or b themselves (that is, you can't point them at different objects) in any way that the caller can see. But you can swap the contents of the objects they refer to.
BTW, the above is rather hideous from an OOP perspective. It's just an example. Don't do it.
I'm going to be reallllyyyy annoying and pedantic here because the word "value" has a very specific meaning in Java, which people often don't often understand, especially when the variables hold references to objects.
I am going to assume the question asks for this behavior:
x = initialValueForX;
y = initialValueForY;
swap(x, y);
// x now holds initialValueForY;
// y now holds initialValueForX;
This is not possible because Java passes all arguments to methods by value. You can never change the actual value stored inside of x and y this way.
You can, however, if x and y hold references to objects, change the properties of the two objects in such a way as to make the printed values look like each other's initial values:
x = initialValueForX;
y = initialValueForY;
swap(x, y);
System.out.println(x); prints what looks like initialValueForY
System.out.println(y); prints what looks like initialValueForX
This works if your understanding of value is what the object looks like, rather than what the identity of an object is. Usually, that is acceptable.
(Was going to give a good example here, but cHao already did. Plus others pointed out that this was a duplicate question anyway.)

Java array - from test

In my Java test was the next question:
there is the next method:
public void changer(int[] x, int y) {
x[y] = x[y] +3;
y = y * 2;
}
We have array named a, with the values:
2,4,0,1,-6,3,8,7,5
if b = 3
what will be a and b values after the next call:
changer(a,b);
My answer was:
b = 6
a = 2,4,0,4,-6,3,8,7,5
I've tested it on BlueJ and got the same answer, but the tester wrote: wrong !
what do you say?
You are right about array values, but wrong about b value.
When you call a method, java passes everything by value, that mean that changing y only changes the value locally, and the change is not reflected on b.
However, when passing arrays and objects, a value representing a pointer to the array is passed. That means that x = new int[8] does not alter a at all, since as it happens for y the change is not reflected to a. However, changing array members or object properties works as you expected, cause a and x both point to the same array in memory.
from the scope where changer is called b doesn't change, because Java is pass by value and b is a primitive. So b would still be 3 after the method call. The statement in changer:
y = y * 2
after changing the value in the array effectively does nothing.
Your answer for a is correct.
b should still be 3. Passing an integer passes it "by value", so it is essentially a copy of b that goes into the changer method.
B won't be changed because it is a primitive passed as a method parameter. In that case a local copy is made, which is in this case multiplied by two. The original b will not be affected by this though. The array is changed because arrays (even arrays of primitives) are Objects in Java, so the reference to the array is passed into the method and changes to the array (via the reference) are reflected in the one and only array - no copy is made in this case.
You're confusing values and references, and thinking of the y value as if it's a reference.
The first line
x[y] = x[y] +3;
sets the value of the yth element of the array. The following line y = y * 2;
changes the value of the parameter but doesn't alter the array setting.

Categories

Resources