-2

I'm having a problem with Java. Why does the following code return null?

public class TestClass {
    public String top,top1,top2,top3,top4;

    public TestClass(){
        changeTop(top);
        changeTop(top1);
    }

    public void printTop(){
        System.out.println(top);
    }

    public void changeTop(String reference){
        reference="lolly";
    }

}

When I run the following:

TestClass x =   new TestClass();
x.printTop();

It also returns null. I don't understand it because i thought I was passing a reference to the ChangeTop. How can I fix this? I want to give the name of the parameter to a method to change it.

Bosiwow
  • 2,025
  • 3
  • 28
  • 46
  • I know i can just do this.top="lolly", but that's not what I want. imagine we have a top1,top2,top,3... . Is it impossible to simply give the name to a method that changes the value? – Bosiwow Dec 02 '14 at 16:16
  • 2
    @ZouZou: This question is not a duplicate of 'Is Java “pass-by-reference” or “pass-by-value”?' the implementation here is wrong. changeTop method is assigning "lolly" to the parameter 'reference' itself and not to 'top'. Thus top is always null. – Nazgul Dec 02 '14 at 16:17
  • 1
    @Nazgul That's why I revert my closing. – Alexis C. Dec 02 '14 at 16:17
  • Your field isn't changing because you aren't changing it. There's literally nowhere in your entire program where you do anything but declare `top`... – tnw Dec 02 '14 at 16:18
  • Thanks ZouZou. +1 for the courage to accept your mistake. Appreciate that. – Nazgul Dec 02 '14 at 16:19
  • To clear this out, I don't want to hardcode the name of the field in my method. I wnat to create a method, where I can pass a fieldname to and sets that field to a specific value. – Bosiwow Dec 02 '14 at 16:19
  • 3
    @Nazgul I disagree - this question is prompted by a fundamental misunderstanding of how reference semantics work in Java. The linked answer explains what can and cannot be done and thus completely covers this case. – Andrzej Doyle Dec 02 '14 at 16:19
  • Well maybe the OP doesn't understand method parameter semantics but the code example doesn't give that picture. Its typically not an example of wrong parameter passing or manipulation. its an example of incorrect assignment. – Nazgul Dec 02 '14 at 16:21
  • 1
    @Nazgul Re-reading the question, I think I did right closing this. The OP expects `changeTop(top);` in the constructor to change the value of top when he calls `new TestClass();`. Thus the closing vote was correct actually. – Alexis C. Dec 02 '14 at 16:23
  • i agree with ZouZou and Andrzej, the linked question should cover this. i think what the OP isn't getting here is that what is passed into changeTop is a copy of the reference (passing refs by value) in the top instance variable, so nothing that happens in the method affects the original reference. – Nathan Hughes Dec 02 '14 at 16:35

1 Answers1

0

Try this :

public void changeTop(String reference){
    this.top = reference;
}

And run this :

TestClass x =   new TestClass();
x.changeTop("lolly");
x.printTop();

Edit

In case of having a lot of variables, try to change your TestClass to this :

public class TestClass {
    public List<String> tops;

    public TestClass(List<String> newTops){
        changeTop(newTops);
    }

    public void printTop(){
        System.out.println(tops);
    }

    public void changeTop(List<String> tops){
        this.tops = tops;
    }

}

Try to run this :

public static void main(String[] args) {
    List<String> tops = Arrays.asList("lolly", "colly", "solly", "molly");
    TestClass x = new TestClass(tops);
    x.printTop();
}

And the output :

[lolly, colly, solly, molly]
Anarki
  • 373
  • 5
  • 20
  • To clear this out, I don't want to hardcode the name of the field in my method. I wnat to create a method, where I can pass a fieldname to and sets that field to a specific value. – Bosiwow Dec 02 '14 at 16:22
  • That's what I did in the second snippet – Anarki Dec 02 '14 at 16:25
  • And What should i write if I wanted to change top2,top3 or top4? – Bosiwow Dec 02 '14 at 16:27
  • @Bosiwow You can't do that in Java. Sorry. (Unless you play around with reflection, but that's an awful way to do this.) – ajb Dec 02 '14 at 16:27
  • @Bosiwow wait a moment i'll show how to do this – Anarki Dec 02 '14 at 16:28
  • 1
    @Bosiwow I can't give an answer any more since this is closed, but please consider not having five variables named `top1`, `top2`, ... Instead, create an array, or better, create a `Map` whose keys are the strings `"top1"`, `"top2"`, etc. Then you can actually do what you want. Plus any time you have a whole flock of variables with similar names and the same type, you should consider not having them be separate variables. – ajb Dec 02 '14 at 16:29
  • Yeah, I wanted to create a map, but then I thought that would be an overkill. – Bosiwow Dec 02 '14 at 16:31
  • 1
    @Bosiwow take a look to my edit – Anarki Dec 02 '14 at 16:36