Value of calling method is modified - java

In the following code why output is 0 42 42 rather than 0 0 42.
In Java object is not passed by reference so why value of t.x was modified to 42?
class Two
{
byte x;
}
class PassO
{
public static void main(String [] args)
{
PassO p = new PassO();
p.start();
}
void start()
{
Two t = new Two();
System.out.print(t.x + " ");
Two t2 = fix(t);
System.out.println(t.x + " " + t2.x);
}
Two fix(Two tt)
{
tt.x = 42;
return tt;
}
}

Because what's being passed around in Java is the value of the pointer to the object. Thus when you do tt.x=42, you are changing the original t.x to have a value of 42. And when you return tt you are actually returning the same pointer, so infact t and t2 point to the same instance of the object.

In Java object is not passed by reference so why value of t is
modified to 42?
The value of t is not modified to 42. t.x is modified to 42.
Java is always pass-by-value. The difficult thing to understand is
that Java passes objects as references and those references are passed
by value.

Yes it is passed by value. The value is the reference. t is a pointer to a new Two(). You pass the value that t is referring too and point to it with tt.

Your method fix is not really testing passed by value adherence. If you were really testing for passed by value adherence the method should be something like below:
Two fix(Two tt)
{
// Create a brand new instance of Two
Two newTwo = new Two();
newTwo.x = 42;
// Assign the new reference to the passed in value.
tt = newTwo;
return tt;
}
In your original fix method you are just mutating the passed in object.

Related

Unable to understand the issue "call By Reference" [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
In Java, object reference is used for call by reference and variables are used for call by value.
Here’s an example:
class Foo{
int x;
int y;
}
public class CallByRef {
public static void main(String[] args) {
Foo foo = new Foo();
foo.x=5;
foo.y=10;
System.out.println(foo.x+", "+foo.y);
getFoo(foo);
System.out.println(foo.x+", "+foo.y);
}
static void getFoo(Foo f){
f.x=2;
f=new Foo();
f.x=10;
}
}
Output:
5, 10
2, 10
Why this is happend?
x should be 10 as I modified its value with f.x=10
Is it correct that f=new Foo() will create new object in heap and not point to prevoise reference?
In method getFoo, variable f is a local variable.
When you call getFoo(foo) from main, this variable indeed refers to foo.
But once you set f = new Foo(), it refers to a different object.
Therefore, at that point, changing f.x does not affect foo.x.
Here is a basic description what happens in your case as an example
// Creating a new object of Foo
// The variable foo now stores a VALUE!!! to the memory where the
// Instance of foo is stored
Foo foo = new Foo();
// accesing the instance of Foo over the value to the reference in the memory
// and set x to 5
foo.x = 5
// accesing the instance of Foo over the value to the reference in the memory
// and set y to 5
foo.x = 10
// Print out x and y of the instance of Foo where the value of the reference to memeory points to
System.out.println(foo.x+", "+foo.y);
now to what get Foo does
// The instance f of Foo holds the value to the reference in the memory
// Lets call it 1234567 as example
static void getFoo(Foo f){
// The object in the memory 1234567 is going to have x changed
f.x=2;
// The VALUE of the reference is changed, lets say it now refers to the memory 123456789 where a new instance of Foo is stored now
f=new Foo();
// The object in the memory 123456789 is going to have x changed
f.x=10;
}
Lets go back to your last output and what it does print now
// So in your getFoo() Call your first action was to change the value of x
// on the object with the value to the reference which you gave as a parameter
// hence it prints 2
// The new instance of the Object Foo that is stored somewhere else in the memory should be garbage collected soon, since no variable actually holds the VALUE to the reference anymore
System.out.println(foo.x+", "+foo.y);
The most import part to understand is, that the references to the object in a variable or parameter are actually stored as values to the memory. Due to this your getFoo() method simply changes the value of the reference to the instance of the object, but can never change the reference itself
I think first case is clear for you, ie the value 5,10.
After that by calling getFoo() method and passing the same object foo is passing as argument. And in getFoo() method the instance variable value of the same object(foo) is changed to 2. But after that it s creating new object using new keywork and assigning another value.
ie.
foo => x=2(new value) and y=10(not changed, so it takes old value)
f => x=10 and y=0(not assigned)
And you are printing foo's values.
Hence the result 2,10

Confusion in passing an object to a function [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
while learning C language I have learned that when you pass a variable to a function. you are not passing the variable itself you are passing a copy of it so the actual varible's value will not change unless the function returns a value and you assign that value to the variable.
but I just executed this program and this happened when I passed "Newobj" object to a "changer" function and then change the values of the variables and then print the new variables values it is working. It should not happen right? because I am sending the copy of "Newobj" to "copyobj". explain please I am confused.
Note: Explain in detail please. My brain is slow. I know the concepts of c and few concepts of c++;
here is my code:
public class PassObjects {
int regno;
String name;
double per;
PassObjects(int a,String s,double p){
regno=a;
name=s;
per=p;
}
PassObjects changer (PassObjects copyobj){
copyobj.regno=797;
copyobj.name="Srimanth";
copyobj.per=70.9;
return copyobj;
}
public static void main(String[] args){
PassObjects Newobj= new PassObjects(86,"srimanth",85.4);
System.out.println("The original values of Instance variables are "+Newobj.regno+" "+Newobj.name+" "+Newobj.per);
Newobj.changer(Newobj);
System.out.println("The changeed values of Newobj are "+Newobj.regno+" "+Newobj.name+" "+Newobj.per);
}
}
output is here:
The original values of Instance variables are 86 srimanth 85.4
The changeed values of Newobj are 797 Srimanth 70.9
What you are doing is passing a pointer to an object. You are effectively modifying the PassObjects object.
There is a difference between a reference type and a value type. For example, a function that takes an integer and modifies it will indeed receive a copy of that integer.
public void add(int x)
{
x = x + 1;
}
However, an array of ints is also a reference type.
When you call this function using the following code:
int x = 5;
add(x);
// X will still have a value of 5.
This is because x is a value-type. You call the function and pass in a copy of the integer.
However, when you create an object, you do not pass a copy of the entire object. See code below.
public void ChangeName(SomeObject x, String newname)
{
x.name = newname;
}
SomeObject x = new SomeObject("thename");
ChangeNameTo(x, "newname"); // As the comment below pointed out, you don't even have to reassign.
//x.name will have the value "newname" now.
You can read more here and here.
Java does manipulate objects by reference, and all object variables are references.
That means u only created a new reference to the same object and when u changed the values then it gets changed in actual object.

Java and pass by reference

I'm not terribly familiar with Java, I'm fiddling with a simple binary tree and ran into something that I dont understand...
in the following snippet, Add() passes AddHelper() a number and a reference to the root node, mRoot. However, mRoot is always null, even after the first call to AddHelper()
If, however, I change I change AddHelper() such that it uses mRoot directly (instead of being passes in by reference), then it works... I dont understand why/how this would be any different, functionally.
Node mRoot;
public void Add( int num ) {
AddHelper(num, mRoot);
}
private void AddHelper( int num, Node node ){
// if I change 'node' to 'mRoot', it works. why?
if ( node == null ) {
node = new Node(num);
}
else {
...
}
assuming you have declared mRoot as a Node in your class already let me answer your question.
java is always pass by value when you pass mRoot to your method you are passing bytes that are referring the object in the heap. for example when you do this with a primitive variable
int i =5;
int j=i;
the bytes stored in i is transferred to j. similarly when you do this
Object obj = new Object();
Object newObj = obj;
the bytes stored in the reference variable obj is getting transferred to the reference newObj. as obj holds the reference to the Object instance the same reference is held by newObj.
you can see that
i = 5;
j=i;
j=10; // this doesn't change the i value
same way
obj = new Object();
newObj = obj;
newObj = new Object(); // this doesn't change the obj
hope you understood.
EDIT:
to answer your question in the comment, consider the following code.
class Sample {
Object originalObj;
public static void main(String[] args) {
System.out.println(originalObj); // prints null
tryToCreateInstance(originalObj);
System.out.println(originalObj); // still prints null
createInstance(originalObj)
System.out.println(originalObj); // prints the object hashcode
originalObj = returnInstance(originalObj);//returns the same reference as originalObj
//is already initialized, if it had been null
// this would have returned a new object
System.out.println(originalObj); // prints the object hashcode
}
public void tryToCreateInstance(Object obj1){
if(obj1==null) {
obj1 = new Object(); // relate this with my answer above
// this wont change what originalObj refers
}
}
public void createInstance(){
if(obj==null) {
originalObj = new Object(); // refers to the instance variable originalObj
// hence will affect what originalObj refers
}
}
public Object returnInstance(Object obj1) {
if(obj1==null) {
return new Object(); // returns a new object
}
else {
return obj1;
}
}
}
This is because you are not setting mRoot in your first case. Even though you are setting a node to new Node(num);, you are not setting mRoot. To set mRoot:
if ( node == null ) {
node = new Node(num);
this.mRoot = node; //depending on your logic
}
else {
...
}
Jave is pass by value always. For example, mRoot points to Object X. When you pass mRoot to AddHelper, now node will point to Object X. And then you re-initialize node to new Object (say Object Y). But the previous mRoot still points to Object X.
Hence you need to set mRoot back to Object Y.
When we say pass by value, for primitives the value is copied. But in case of Objects, the object reference is copied (but not the object is duplciated). So if you pass a String reference to a function, the function argument will point to the same String only (as it has copied the object reference which can be though of as a pointer)

why identifier of a wrapper class object does not work as a reference variable

My question involves wrapper classes. I know that when we store a primitive type literal by using wrapper classes, we are storing it as a object of that wrapper class so object's identifier will be a reference variable (somehow like a pointer in c++). For instance, in Integer wi = new Integer("56"), wi is a reference variable. But if that is true:
Why can I do wi++ or wi +=2? Why does compiler deal with those reference variables like normal primitive variables? Doesn't a reference variable store reference of a object?
Given Integer wi = new Integer("56") and int pi = 56, why does (wi == pi) returns true. Isn't wi supposed to store a reference (address)?
And another question: When a reference variable is passed to a method as parameter it counts as passing by reference so the modifiction that happens
to that reference variable should affect it's value but it doesn't:
public class Main {
void show(Integer x){
x *=100 ;
}
void goo(int x){
x *=100 ;
}
public static void main(String[] args) {
Main mn = new Main() ;
Integer wi = new Integer("86");
int pi = 86 ;
mn.goo(pi);
System.out.println(pi); //output = 86
mn.show(wi);
System.out.println(wi); //output = 86, shouldn't it be 8600?
}
}
the statement mn.goo(pi) passes the copy of value 86 while mn.show(wi) passes the copy of reference variable which holds the same object.
why can i do this? wi++ or wi +=2 .i mean why does compiler deal with those reference vriables like normal primitve variables?(doesn't a reference variable store reference of a object?)
Because of the concept of autoboxing and auto-unboxing, wi is converted to primitive, incremented, then then converted back to Wrapper
2.or if we have==>" Integer wi = new Integer("56") " and "int pi = 56" . why does (wi == pi) returns true. isn't wi supposed to store refernce (address)
This is because for Integer wrapper classes, the == will return true for the value till 128. This is by design
For your doubts regarding passign primitives and object references, Please study these programs
class PassPrimitiveToMethod
{
public static void main(String [] args)
{
int a = 5;
System.out.println("Before Passing value to modify() a = " + a);
PassPrimitiveToMethod p = new PassPrimitiveToMethod();
p.modify(a);
System.out.println("After passing value to modify() a = " + a);
// the output is still the same because the copy of the value is passed to the method and not the copy of the bits like in refrence variables
// hence unlike the reference variables the value remains unchanged after coming back to the main method
}
void modify(int b)
{
b = b + 1;
System.out.println("Modified number b = " + b);
// here the value passed is the copy of variable a
// and only the copy is modified here not the variable
}
}
The output is
Before Passing value to modify() a = 5
Modified number b = 6
After passing value to modify() a = 5
Passing object reference to method
class PassReferenceToMethod
{
public static void main(String [] args)
{
Dimension d = new Dimension(5,10);
PassReferenceToMethod p = new PassReferenceToMethod();
System.out.println("Before passing the reference d.height = " + d.height);
p.modify(d); // pass the d reference variable
System.out.println("After passing the reference d.height = " + d.height);
// the value changes because we are passing the refrence only which points to the single and same object
// hence the values of the object are modified
}
void modify(Dimension dim)
{
dim.height = dim.height + 1;
}
}
The output is
class PassReferenceToMethod
{
public static void main(String [] args)
{
Dimension d = new Dimension(5,10);
PassReferenceToMethod p = new PassReferenceToMethod();
System.out.println("Before passing the reference d.height = " + d.height);
p.modify(d); // pass the d reference variable
System.out.println("After passing the reference d.height = " + d.height);
// the value changes because we are passing the refrence only which points to the single and same object
// hence the values of the object are modified
}
void modify(Dimension dim)
{
dim.height = dim.height + 1;
}
}
The output is
Before passing the reference d.height = 10
After passing the reference d.height = 11
The java compiler automatically inserts intValue and Integer.valueOf calls to convert between int and Integer. For example, here's a code snippet from the question:
void show(Integer x){
x *=100 ;
}
And here is what really happens:
void show(Integer x) {
int unboxed = x.intValue();
unboxed *= 100;
}
As you can see, the line x *= 100 does not really change the Integer object you pass in, it only changes the int value extracted from that Integer object.
In a similar way, the code wi == pi from the question actually means wi.intValue() == pi, which explains your observation.
Java uses the "call by value" concept as described in detail here
So in your case x *=100 ; in method show only updates the local variable
Compiler unboxes wi to primitive data type.So now, it is a primitive data type,since everything in Java is pass by value, changes in the formal arguments will not affect actual arguements.
mn.show(wi);

Only array is being modified

This is the code I have, please look at it before you read the question
package ict201jansem2012;
public class Qn3b {
public static void main(String[] args) {
int a = 1;
int b[] = {4,5};
String s = "Good luck!";
method1(b[1]);
System.out.println("(1) b[0] = "+b[0]+"; b[1] = "+b[1]);
method2(b);
System.out.println("(2) b[0] = "+b[0]+"; b[1] = "+b[1]);
method3(a);
System.out.println("(3) a = " + a );
method4(s);
System.out.println("(4) s = " + s );
}
public static void method1(int b) {
b = 7;
}
public static void method2(int[] b) {
b[0] = 3;
}
public static void method3(int a) {
a = 3;
}
public static void method4(String s) {
s = "UniSIM";
}
}
Output:
(1) b[0] = 4; b[1] = 5
(2) b[0] = 3; b[1] = 5
(3) a = 1
(4) s = Good luck!
So my question is ,
This is intresting for me to know as learning programmer. The int b array 0 index value has changed, but not the other variables like the String s and int a. Before i ran this program I roughly thought in my mind that the variable will change their values as the methods are called ,this is because the method is being called and the main method vairable such as a,s and b array are passed and then they are being modified.
So in a nutshell why is that the b array 0 index is changed while the other variables are not changed?
Because you said you were a beginner programmer, I'll do a little writeup to explain (or try to explain) exactly what is happening.
It is because you are passing an argument to your method1 - method4 methods
These arguments, themselves, are references to other objects.
When you use the assignment operator, an equals sign, you overwrite that reference for the value in the current scope - where variables can be 'seen'.
In your code:
In the case of method1 you are creating a new reference, the variable can only be seen within that scope. That is, when you then go b = << expr >> you are assigning the variable b within method1's scope the value, not b in the main scope. The same is true of your method3 and method4 methods, you are assigning a new value to the respective variables within that scope, as you are creating new references rather than altering the original objects.
But, method2's code behaves differently, this is because you are mutating the object inside that code. You are altering the object directly - rather than creating a new reference inside that scope.
Consider the code below
int[] array = new int[] {1, 2};
public void test()
{
method1(array);
System.out.println(array[0] + ", " + array[1]);
method2(array);
System.out.println(array[0] + ", " + array[1]);
}
// because we are working with objects, the identifier, can be different to the arrays identifier
// in this case, I've chosen to use 'a' instead of 'array' to show this
public void method1(int[] a)
{
// this mutates the array object
a[0] = 2;
}
public void method2(int[] array)
{
// this overwrites the method2.array but not the global array
array = new int[] { 1, 2, 3 };
}
We create a new array, with identifer 'array' in the global scope. (In Java, this would be the classes own scope)
In method1, we take an argument, which is the same object being passed as the global array object, so when we mutate it, both objects will change. So, the first print statement will be
"2, 2"
Where array[0] has been altered
N.B. Because we dealing with objects, the 'name' of the variable doesn't matter - it will still be a reference to the same object
However, in method2, we take an argument, like in method1, but this time we use the assignment operator to assign that variable to a new value in the scope that it's currently in - so the global array isn't altered, so we still print out
"2, 2"
For a beginner programmer, I would personally write a few test programs where you get to fully understand how variables and scopes work.
But just know, everytime you create a new block of code, a new scope is created, local variables to that scope can only be seen in that scope and ones below it.
For instance:
public void test()
{
int a = 5;
method1(a);
System.out.println(a); // prints 5
}
public void method1(int a)
{
// a is only viewable in the method1 scope
// and any scopes below it, that is, any scopes created within method1
// and since we use an assignment operator, we assign method1.a a value, not global 'a' a value
a = 123;
if (true)
{
// this is a new scope, variables created in this block cannot be seen outside it
// but can see variables from above it
System.out.println(a); // prints 123
}
}
Here, we create a new scope inside method1 inside the if statement, which can see a above it. However, because method1 and test's scopes are both independent, when we use the assignment operator, we assign the value of a to the local scope. So a is different in both test and method1
I hope you understand better now.
I'm not very good at conveying things, but if it even helped a little bit in understanding scopes I did well, plus, it was fun.
Java is pass-by-value, but most values (everything that's not a primitive, in this case int[] and String) are references, which means they act like pass-by-reference.
Here's a nice writeup: http://javadude.com/articles/passbyvalue.htm
arrays are special type of objects and memory will be allocated on HEAP. When you pass array as parameter to method it will be pass as reference-value (copy of the reference).
This means initial b and this new reference points to same object. Unless new reference points to another object, changes on this reference will reflect on same object. That is why you are seeing value reflected on original array.
All of the values were passed TO the inner methods, but the inner methods returned nothing. However, method2 modified the internal value of the array that was passed to it, so that inner value appeared modified on return.
Note that method2 is the only one where you did not assign to the variable (parameter) itself, but rather assigned to an element of the object whose reference was passed in.
There is a critical difference between modifying the reference (pointer) to an object, and modifying the object itself.

Categories