-3

I thought you can't change the value of a String once it has already been initialized to a value? Well apparently I can in my program below.

public class Pekka {
    public static void main (String[] args){
        Person p = new Person("Pekka Mikkola", "040-123123");

        System.out.println(p.getName());
        System.out.println(p.getNumber());
        System.out.println(p);
        p.changeNumber("000-0001");
        System.out.println(p);



    }
}

class Person {

    private String name, number;

    Person(String name, String number){
        this.name = name;
        this.number = number;
    }

    public String getName(){
        return name;
    }

    public String getNumber(){
        return number;
    }

    public void changeNumber(String newNumber){
        number = newNumber; 
    }

    @Override
    public String toString() {
        return getName() + "    number: " + getNumber();
    }
}

My output:

Pekka Mikkola
040-123123
Pekka Mikkola    number: 040-123123
Pekka Mikkola    number: 000-0001

So I can apparently change the value of the string number as many times as I want. How come? I can change the value of the variable "number" in the changeNumber method even though it has already been initialized? I thought Strings in Java once initialized can't be changed?

user5846939
  • 415
  • 4
  • 11
  • `toString()` will return a new string (String object on the heap) on every call. – PeterMmm Mar 06 '16 at 17:18
  • 2
    You can change a variable to point to a new reference, a new real object. You can't modify the contents of an immutable object. – Louis Wasserman Mar 06 '16 at 17:19
  • You let the field `number` point to another object, another String. Every String object can be shared, as you cannot change its internal value. – Joop Eggen Mar 06 '16 at 17:20

3 Answers3

2

You can't change a String's value*, but you can assign a new, different String to a variable (unless the variable is final).

Your code is assigning a new String to the number variable:

public void changeNumber(String newNumber){
        number = newNumber; 
    }

The old String isn't being modified - it's being discarded.

* Actually, there are ways to do this, using reflection, but it's not usually a good idea.

DNA
  • 42,007
  • 12
  • 107
  • 146
0

You are not changing the value of a String, but assigning your variable number to a new String.

pczeus
  • 7,709
  • 4
  • 36
  • 51
0

Strings in Java are immutable in the sense that once a string is allocated, its value cannot typically be changed. However, the allocation that the variable points to can change.

For example, consider the following:

String test = "test";

Memory gets allocated on the heap to store the string "test". Now, if the following code is run:

test = "test2";

Then a new allocation is made to store the string "test2", and the variable test now points to that allocation. The allocated value of a String is not changed, but the variable can always point to a different allocation. The only way to make a String variable's value not possible to change is to declare it as final.

M.S.
  • 1,091
  • 1
  • 11
  • 27