0

This is a much simplified version of a class file I'm working on, I've just used these classes to show my problem.

public class Test {
    private String string1 = null;
    private String string2 = null;

    private void setString(String s) {
        s = "hello";
    }

    private void set() {
        setString(string1);
        setString(string2);
    }

    public void print() {
        System.out.println(string1);
        System.out.println(string2);
    }

    public void initialise() {
        set();
        print();
    }  
}

public class StringTest {
    public static void main(String[] args) {
        Test test = new Test();
        test.initialise();
    }
}

Anyway, basically, after this the two string variables are still null. What causes this problem? and how can I get around it? (Still learning the fundamentals of java - if that's relevant).

Any help/guidance is greatly appreciated.

Ari
  • 1,026
  • 6
  • 20
  • 31

7 Answers7

6

Because a String is immutable, any change you make inside the method will be local to that method.

private void setString(String s) {
   s = "hello";
}

s can't be changed.

I can think of two options.

Option 1

Make s an instance variable (field) and change your method.

public class Test { private String string1 = null; private String string2 = null; private String s;

private void setString(String s) {
    this.s = "hello";
}

Option 2

Pass in a StringBuilder/StringBuffer instead of String.

adarshr
  • 61,315
  • 23
  • 138
  • 167
  • 3
    This only explains part of the story; the other part is that `s` is a reference to a `String` object, and that *can* be modified. – Oliver Charlesworth May 02 '12 at 13:52
  • @OliCharlesworth `s` is a *copy* of the reference to a `String` object. So, even if you were to modify the reference by re-assigning, the original String wouldn't be changed (that's considering String wasn't immutable in the first place) – adarshr May 02 '12 at 13:55
5

Your problem is that Java is pass by value, so your setString method does not do anything. To change the value of string1, you need to have string1 = xxxx; somewhere in your code. For example:

private void set() {
    string1 = getDefaultString();
    string2 = getDefaultString();
}

private String getDefaultString() {
    return "hello";
}
Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
1

You are setting the value of "s" not string1 or string2

try something like.

private void setString(String s) {
        string1 = "hello";
        string2 = "world";
    }
MrWaqasAhmed
  • 1,479
  • 12
  • 12
1

By making this assignation

 s = "hello";

weare creating a new object. It will have a different memory address than the one passed with setString(string1);

We would need to change the object received at

 private void setString(StringBuilder  s) { ... }

instead of creating a new one. We need to use exactly the same object we were passed in this method. Can't create a new one, as the caller method wouldn't notice (parameters in Java are never output parameters).

As Java's String is inmutable, we can't change its content: just create a new String object.

As @adarshr pointed out, we can use StringBuilder or StringBuffer, which are mutable, and change their content. But we can't just replace String with StringBuilderin you code. We have to make sure that:

  1. The StringBuilder is initialized before being passed to setString().
  2. The StringBuilder is not created again inside setString() (we are using the same one we were passed).

So, replacing this in your code should work:

private StringBuilder string1 = new StringBuilder();
private StringBuilder string2 = new StringBuilder();

private void setString(StringBuilder  s) {
    s.append("hello");
}
J.A.I.L.
  • 10,644
  • 4
  • 37
  • 50
0

you misunderstand of java parameter passing, try public void setString1(String s) { string1 = s; }

user1335794
  • 1,082
  • 6
  • 12
0

What are you trying to initialize the values of string1 and string2 to? The two member variables start out being null.

If I were to treat Test class as a POJO (plain old Java object), I would add getter/setter methods as follows:

public class Test {

  private String string1;
  private String string2;

  public String getString1() {
    return this.string1;
  }

  public String getString2() {
    return this.string2;
  }

  public void setString1(String s) {
    this.string1 = s;
  }

  public void setString2(String s) {
    this.string2 = s;
  }

  /*
   * Additional methods
   */
  public void set() {

    setString1("hello");
    setString2("world");
  }

  public void print() {

    System.out.println(this.string1);
    System.out.println(this.string2);
  }

  public void initialize() {

    set();
    print();
  }
}
Web User
  • 7,438
  • 14
  • 64
  • 92
  • There is nothing in his requirement that points to the need for setters. Why would you add some? – assylias May 02 '12 at 14:01
  • I was just trying to illustrate a common practice with POJOs in general. Those methods are not specifically part of the answer. – Web User May 02 '12 at 14:03
  • 1
    I understand - I was just pointing out that the general approach should be to make your objects as immutable as possible, unless you **have to** make them mutable, not the other way round. – assylias May 02 '12 at 14:09
-2

ur application is assigning the hello word in parameter s..but the variable s is a parameter type thats y the reflection of s will be in setString() method block...not anywhere else...use instance variable or static variable to see the reflection of ur assignment.

user1319054
  • 41
  • 1
  • 5