-1

So I was testing some code and here they are:

public class Phone {

    String phoneNumber = "1234";

    void setNumber(){
        String phoneNumber;
        phoneNumber = "4321";
    }
}

public class TestPhone {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Phone p1 = new Phone();
        p1.setNumber();
        System.out.println(p1.phoneNumber);
    }

}

Output:

1234

Why not 4321? I called setNumber so phoneNumber should be assigned to 4321, what am I missing?

janos
  • 120,954
  • 29
  • 226
  • 236
OPK
  • 4,120
  • 6
  • 36
  • 66
  • You are declaring it again in the method. That would shadow the instance variable. – Sid Dec 20 '14 at 18:41
  • By default the preference is given to the local variable with same name. So in method setNumber String phoneNumber is a new local variable which is updated not the instance variable. To update the instance variable use this key word – Parth Satra Dec 20 '14 at 18:41
  • by the way a decent IDE (Android Studio/WebStorm is mine, there are many) will warn you about this condition and generally save you zillions of hours on such things :) – RobP Dec 20 '14 at 18:46
  • Your question title makes me think that you *know* the difference between a local variable and an instance variable... – Chris Cirefice Dec 27 '14 at 09:33

10 Answers10

5

The local variable phoneNumber shadows the instance variable with the same name.

void setNumber(){
    String phoneNumber;
    phoneNumber = "4321";
}

So this code sets the local variable, doesn't change the instance variable.

If you wanted to change the instance variable, you would have to disambiguate, using the this. prefix, like this:

void setNumber(){
    String phoneNumber;
    this.phoneNumber = "4321";
}

... or better yet, just remove the pointless local variable entirely... (like you said @RobP!)

Community
  • 1
  • 1
janos
  • 120,954
  • 29
  • 226
  • 236
1

This is because you are actually printing the value of the proterty phoneNumber, defined in the class Phone. The phoneNumber in the setNumber method is just a local variable.

If you want to modify the value of the property, you can just do:

phoneNumber = 1214728;

or

this.phoneNumber = 1214728;

without defining a local variable with the following statement:

String phoneNumber; // this creates a local variable, you don't want to modify this local variable, but the property!

nbro
  • 15,395
  • 32
  • 113
  • 196
1

By default the preference is given to the local variable with same name. So in method setNumber String phoneNumber is a new local variable which is updated not the instance variable. To update the instance variable use this key word

Something like

this.phoneNumber=4321

Parth Satra
  • 513
  • 2
  • 16
1

The problem is here.

String phoneNumber = "1234";

void setNumber(){
    String phoneNumber;
    phoneNumber = "4321";
}

When you create a second String phoneNumber in your setNumber function it overrides the first one within that function with a local variable. To fix this you'll either want to rename the variables to be different or use a this accessor, or simply remove the local variable such as:

String phoneNumber = "1234";

void setNumber(){
    this.phoneNumber = "4321";
}

Or

String phoneNumber = "1234";

void setNumber(String newPhoneNumber) {
    phoneNumber = newPhoneNumber;
}

p1.setNumber("4321");
John Cipponeri
  • 882
  • 8
  • 12
1

Inside the method setNumber you are declaring a new variable with name phoneNumber and then assigning it the value "4321". The case is similar like

void setNumber(){
    String foo;
    foo = "4321";
}

You can correct your method by using the proper variable or using this before the variable name

void setNumber(){
    phoneNumber = "4321"; // this.phoneNumber = "4321"
}
sol4me
  • 15,233
  • 5
  • 34
  • 34
1

It because you only print the value of the instance variable, then inside the method you declared a separate variable also called as Local variable.

if You want to change the value of an Instance variable which is phoneNumber = "1234" that is outside the method.

Inside your Method setNumber(), remove your Local variable declaration, use a "this" keyword to refer the phoneNumber property to make a change on it.

void setNumber() {
this.phoneNumber = "4321"
}

In this case the method setNumber() when it is called by the object, he will change the current value of the phoneNumber variable from "1234" to "4321".

Yel
  • 101
  • 2
  • 6
0

The code String phoneNumber; declares a new variable reference which is different from your global variable. Also the scope of this local variable phoneNumber exists only till the function and could be used only from within the function.

Thus the reference specified by your global var was never actually modified when you tried to change the value.

The simple fix for this is to refer the global variable by either this.phoneNumber or simply removing the new variable declaration.

Playmaker
  • 1,458
  • 1
  • 14
  • 23
0

in your setNumber method, phone number is local.

//try this

public class Phone {

String phoneNumber = "1234";

void setNumber(){
this.phoneNumber = "4321";
}

}

public class TestPhone {

public static void main(String[] args) {

Phone p1 = new Phone();
p1.setNumber();
System.out.println(p1.phoneNumber);
}

}

hakimkal
  • 90
  • 1
  • 12
0

What you do in the method is shadow the property of the class. On assignment, the value 4321 is set on the local variable an not on the property. That way, the local variable hides the variable of the property. When method returns though, the local variable gets out of scope and is marked for destruction, not shadowing the property anymore.

In main, you are printing out the property value, which is of course unchanged despite the call.

Nick Louloudakis
  • 5,856
  • 4
  • 41
  • 54
0

When you declare instance variable and do a declaration again as a local variable they are considered are different variables. For your code to work do the following.

public class Phone {

String phoneNumber = "1234";

void setNumber(){

    this.phoneNumber = "4321";
}

}

public class TestPhone {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Phone p1 = new Phone();
    p1.setNumber();
    System.out.println(p1.phoneNumber);
}

}