Object value doesn't change - java

class smth{
public static void main(String[] args){
private Integer x = new Integer(17);
inc(x);
System.out.print("x="+x);
}
public static void inc(Integer x){
x++;
System.out.println("n="+x);
}
}
output:
n=18;
x=17;
Integer is an object and I don't understand why the value of x did not change in this case.

Cause Integer is immutable object. When you send it to method, new reference to it is created. When you do increment, reference inside method is reassigned to new Integer with value 18 but reference inside main is still referencing to old Integer with value 17.

Integer is immutable. The x++ creates a new object, and rebinds x to refer to it. The change does not propagate back to the caller since the reference to the original x was passed by value.

Any wrapper classes are immutable class.

Because x++, on an Integer object, actually means:
int temp = x.intValue();
temp++;
x = Integer.valueOf(temp);
The x variable is being assigned a new Integer instance. And since parameters are passed by value, the original reference stays unmodified.

It is because Java passes objects to methods by value and not by reference. Upon completing the method call, the object value will be the same in the calling method as it was before passing it. Within the called method, the value can change but the scope of the change is the method to which it was passed.

This is because Integer, a wrapper over the primitive int, is immutable, and Java passed object references by value. Any change made to the object reference inside the method has no effect on the object passed in: the reference is replaced with a reference to a new object, yet the original remains intact because it is immutable.
To address this issue, you need another level of indirection - you can use an array, a mutable int from apache commons, or roll your own suitably designed class.
public static void main(String argv[])
MutableInt x = new MutableInt (17);
inc(x);
System.out.print("x="+x.intValue());
}
public static void inc(MutableInt x){
x.add(1);
System.out.println("n="+x.intValue());
}

It is because the object modifying inside the method incis not the same as the one printed outside this method.
Inside the method inc x is a reference which points to an object. When you run x ++, that reassigns X to reference a new Integer object, with a different value. Thus, you are not modifying your original 'x' variable declared on the main.
You have to return the "pointer" to the new integer object:
public static int inc(Integer x){
x++;
System.out.println("n="+x);
return x;
}
public static void main(String argv[])
Integer x = new Integer(17);
x = inc(x);
System.out.print("x="+x);
}
An Integer, is a Object that contains a single int field. An
Integer is much bulkier than an int. It is sort like a Fedex box to
contain the int. Integers are immutable (source)

Related

Why does the new Integer act as value type int?

public static void main(String []args){
Integer a = new Integer(9);
d(a);
System.out.print(a) ;
}
public static void d(int z){
z=z+2;
}
or suppose I write
public static void main(String []args){
int a = 9;
d(a);
System.out.print(a) ;
}
public static void d(int z){
z=z+2;
}
but the output is the same for both: 9. Can anyone explain me in detail why?
Because JAVA is PASS BY VALUE not PASS BY REFERENCE.
Let us understand it this way,
Your main function has a local variable z whose scope is limited to main only
and your d function has another local variable z whose scope is limited to d only
So, in your d fucntion, you are basically creating a new integer literal 11 and putting it to local variable z whose scope is limited to d function only and not the variable z of main.
In your code with Integer a process called unboxing occurs. The Integer-instance is unboxed to a primitive int when calling your method d. See this to better understand how autoboxing and unboxing works.
As for your z=z+2 inside the method d. Java objects are passed-by-reference, but Java primitives or Immutable objects (like Strings) are passed-by-value. Since your method d has a primitive parameter int it's passed-by-value in this case. Your z=z+2 isn't returned however.
If you would add System.out.println(z); right after z=z+2 it will indeed print 11. So why isn't the a in your main-method changed to 11 and how can you accomplish this? As I mentioned, it's passed-by-value for primitives. You'll need to return the new value and set the a in the main method with it. If you change your code to this it will work:
public static void main(String []args){
int a = 9;
a = d(a);
System.out.print(a);
}
public static int d(int z){
return z+2;
}
Try it online.
As you can see, the void d is changed to int d, and we return the result of z+2. We then overwrite the value of a with this new result with a = d(a); in the main-method.
Java has a concept of AutoBoxing and Auto unboxing for primitive datatypes.
Since primitves like int, float double, long etc are technically not objects, they have their corresponding Classes which can be instantiated with the primitive value to treat them as objects.
So to reduce the pain, java automatically converts int to Integer and Integer to int where ever applicable.
If you are wondering why the addition value has not reflected, though it is an Integer object on performing addition, a new int object will be resulted. so it wont reflect directly. You can return the value from the method you call and assign to it.
Java passes variables by value, not by reference. If you think that passing an object and changing the value of its data member would work, it won't. In that case, too, a copy of that object will be passed, not the original object. The only solution is to declare the variable as static that can be changed from anywhere.
it's all because of Autoboxing and Unboxing feature of java which provide the functionality of converting primitive to object(Wrapper) type and vice-versa. for better understanding you can check here
. I hope it will clear all your doubts.

How actually values get assigned to object reference(actual memory,allocated by new) which are initialized by Constructor?

class box
{
double height,width,depth;
box(double h,double w,double d)
{
height=h;
width=w;
depth=d;
}
}
class boxdemo7
{
public static void main(String args[])
{
double vol1,vol2;
box mybox1=new box(10,12,16);
}
}
In these program in the box class I declared three double type variables, and I initialize those with constructor meaning I set the state of the object which is using the constructor. My Question is height,width,depth got memory allocated for them when declared within box class, so by using constructor they got values 10,12,16 and these values taken by object mybox1. So mybox1's memory location has these values ?or these variables memory has these values and a reference to those are stored to objets referred location ? How memory works while an objects internal state gets the values ?
Primitive types are passed by value, unlike objects. So in this particular case the values 10, 12 and 16 will be assigned to the fields inside your box object. With objects, on the other hand, it will depend on your implementation of the constructor. If you use a simple assignment operator the field will get a reference to the passed object, and changes to the passed object will change the object the field refers to. If you create a new object based on the passed object they will remain independent.
Try this code:
public class Test {
static class sample{
int primitive;
int[] object;
sample(int prim, int[] obj){
primitive = prim;
object = obj;
}
}
public static void main(String... args){
int primram = 0;
int[] objectParameter = new int[1];
sample demonstration = new sample(primram,
objectParameter);
System.out.printf("Old Values: %d, %d%n",
demonstration.primitive,
demonstration.object[0]);
primram++;
objectParameter[0] = primram;
System.out.printf("New Values: %d, %d%n",
demonstration.primitive,
demonstration.object[0]);
objectParameter = new int[1];
System.out.printf("Unchanged Values: %d, %d%n",
demonstration.primitive,
demonstration.object[0]);
}
}
You should get output:
Old Values: 0, 0
New Values: 0, 1
Unchanged Values: 0, 1
Notice that the first value, the primitive, did not change when we incremented our primitiveParameter value, because it had already been passed by value and no longer had any relationship with the primitive field inside the object.
Setting objectParameter[0] did change the value inside our sample object because arrays are objects. When you say object = obj in a constructor you point object to the data that obj points to. Since they both point to the same place, they both see changes.

Strange array behaviour in java. An array with a single int behaves differently than the same program with the int not in an array

Why is there a difference between the following two programs A & B. Shouldn't they run identical? For some reason the changer in the case of the array is changing the original value of the input array.
Program A:
public static void changer(int tester) {
tester = tester*2;
}
public static void main() {
int value = 1;
out.println(value);
changer(value);
out.println(value);
}
which gives me the output:
1
1
Program B:
public static void changer(int[] tester) {
tester[0] = tester[0]*2;
}
public static void main(){
int[] value = {1};
out.println(value[0]);
changer(value);
out.println(value[0]);
}
which gives me the output:
1
2
Changing a value in a called method does not change the value in the calling method. In Program B, you're not changing the array, you're changing a value inside the array, and that is visible in the calling method.
In your first example, you passed an int (tester) to the function, and then assigned a new value to it. Since java is pass-by-value, assignment has not effect outside of the callee scope, and so the original value was not changed in the call site.
In the second example, you passed an int array to the function, and then you did not assign to it, but modeified its content, by assigning to a specific cell inside of it, so the value was changed in the call site as well.
Passing primitive data type ( i.e int, double, long, float, ....) to a function or method will be " PASSED BY VALUE". In program A, the argument passed to method is a primitive data (int), so you just passed a copy of the origin value. Any change to it, will not affect the origin number.
But passing Reference/Object data type (i.e, Array, ArrayList, HashMap,...) to a function will be " PASSED OBJECT BY VALUE," which means the method is given copy of the reference to the object. So any change to it, will change the origin reference. In program B, you passed a reference copy of an array. That is why it has been modified.
When arrays work like pointers. When you use
tester[0] = tester[0]*2;
You are basically telling compiler to update element in memory on location tester[0]
This question had been asked so many times. Java passes everything by value and this is especially true for primitive such as int.
When you pass an int argument, you are passing in the value, not the reference of the variable.
public static void main(String[] args){
int value= 5;
changer(val);
}
public static void changer (int tester){
//A variable call tester holding the value of 5
}
A local variable call tester with value of 5 will be created, because you passed in a value of 5. Variable val itself was not passed in.
Any changes done within the method is merely changing the local variable tester.
This explains why the value of val remains unchanged.
When you pass in an array, it still passes by value, but the value does not contain all the values of individual array element. It will be very inefficient to copy the entire array's value for every method invocation. The value holds the reference of the array. Thus, tester now holds the reference of the val.
public static void main(String[] args){
int[] val= 5;
changer(val);
}
public static void changer (int[] tester){
//A variable call tester holding the reference of val array.
}
Since tester is now pointing at the original array: val. Anything you changed in the method will affect the original array.

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.

pass by reference/value - simple example

I know this issue has been addressed many times - but my Java/C++ knowledge is so weak I can barely understand the answers :-( ... what I'd really like is just a super simple example.
In C++ I could write the following:
void func()
{
int x = 3;
add_one(x);
// now x is 4.
}
void add_one(int &var)
{
var++;
}
What I'd like to see now is the simplest way to achieve the same effect with java.
You can't directly. The closest you can get is to put the value in an object, and pass the reference (by value, so the reference gets copied) into the method.
void func()
{
int x = 3;
int[] holder = [x];
add_one(holder);
// now holder[0] is 4. x is still 3.
}
// container here is a copy of the reference holder in the calling scope.
// both container and holder point to the same underlying array object
void add_one(int[] container)
{
container[0]++;
}
Here I use an array, but the wrapper can be any object.
In java method arguments are pass-by-value, and can't be changed in the function. You must wrap the int - or any other primitive type - in an Object or an array. Passing an Object or an array as a method argument passes a reference which can be used to modify the object.
Java already has Object based wrappers for primitive types, e.g. Integer, but these are immutable by design. Some libraries provide mutable versions of these wrappers; you can also create your own:
public class MutableInt
{
private int val;
public MutableInt(int val)
{
this.val = val;
}
public void setValue(int newVal)
{
this.val = newVal;
}
public int getValue()
{
return this.val;
}
}
void func()
{
int x = 3;
MutableInt wrapper = new MutableInt(x);
add_one(wrapper);
}
void add_one(MutableInt arg)
{
arg.setValue(arg.getValue() + 1);
}
You cannot do this. Java is only pass by value. Primitives are obvious, but the thing that's passed for objects is a reference, not the object itself.
As you can see from the other answers, Java is purely pass by value. Objects are passed by what some call "value-reference". Since an object in java is simply a pointer reference, you can think of the "value" as the address where the object lives on the heap. So when you make a method call, you're copying the "value", aka address, to the method parameter:
Object x = new Object();
foo(x);
During object creation
Heap --> allocate Object (5000)
Variable Declaration
Stack --> allocate local variable (1000)
Variable Assignment
Stack address 1000 set to 5000 (to point to object instance)
So you can see that there are two separate memory allocations here. The "value" of the variable is considered to be it's address on the heap.
Method Call
Stack --> allocate method parameter 8000
Stack address 8000 set to same value as passed parameter 5000
This is why if you reassign an object instance in a method, it does not propagate back to the caller. You would have changed the heap location at stack location 8000. And the calling method's stack location 1000 still has the value 5000 (the original object instance).
Think of it like this in C:
void method(myobject * obj);
You can certainly change fields of "obj", and you can do this locally:
obj = new myobject();
But the caller will still see the original value it passed.
Java has no analog to the & reference operator.
And there are built in classes which can be used for the your purposes. AtomicInteger, AtomicLong, etc... are mutable, though you may suffer a performance hit due to synchronization involved.
I would recommend a generic ValueHolder class to account for all situations where you want to simulate pass by reference:
public class ValueHolder<T> {
private T value;
// getter/setter/constructor
}
Java allows copy by reference for objects and copy by vlaue for primitive types (int,float,etc..). This is so by default and is not subject to change. If you need to change the value of an int inside a function, then you can use the class Integer for example
public int getOneMore(int val) {
return val + 1;
}

Categories

Resources