1

I'm abstracting some things in a class and therefore want to pass different class variables (fields) to the same method and have them incremented. I'm finding that the field does not get modified even though I'm passing it into the method.

I have the following simplified code. First the line that initiates the class variable/field, then the constructor that calls the method, then the method.

public class Demo {
  public Integer countOfOnlyOneSameInTop12 = 0;

  Demo() {
    summarize(countOfOnlyOneSameInTop12);
  }

  private void summarize(Integer countOfOnlyOneSameInTop12) {
    countOfOnlyOneSameInTop12++;
    countOfOnlyOneSameInTop12++;
    countOfOnlyOneSameInTop12++;
    System.out.println(countOfOnlyOneSameInTop12); // 3
  }

  public static void main(String[] args) {
    Demo demo = new Demo();
    System.out.println(demo.countOfOnlyOneSameInTop12); // 0
  }
}

When I step through, I expect to see countOfOnlyOneSameInTop12 incremented at the class level because it is passed into the method by the calling line of code. However the value of the class variable/field does not change even though the value of the variable inside the method does increment by one.

According to the experts then, this is a pass-by-value problem.

My question then, is how do I get around it? I want to add to the value of a class variable inside a method and I want to abstract that class variable/field in order to run several through the same method.

Do I need a class wrapper for the Integer?

Am I taking the wrong approach? Incrementing a class-level counter seems reasonable.

The only alternative I see to trying this in some form is a bunch of code duplication.

See my comment below for how a worked around the Integer problem.

Emma
  • 27,428
  • 11
  • 44
  • 69
jb62
  • 2,224
  • 2
  • 14
  • 23
  • I don't think so - I'm depending on "pass-by-reference" here – jb62 Jul 31 '19 at 19:52
  • 1
    You are incrementing a **copy** of your class variable. – PM 77-1 Jul 31 '19 at 19:54
  • 1
    https://stackoverflow.com/questions/3330864/how-can-i-pass-an-integer-class-correctly-by-reference – PM 77-1 Jul 31 '19 at 20:00
  • As a solution, I created a hashmap with a string key and Integer value - using the key as an identifier for my "counters" I was then able to abstract the method signature to use a String for the key and map.put(key, someValue) did the trick... In case anyone is looking for a way around this kind of problem. Thanks all for the fast response. – jb62 Jul 31 '19 at 20:32
  • @jb62, you can also used an array for this. – Yevgen Jul 31 '19 at 21:14
  • As to your question, it's a pity it was closed, since it seems to go beyond pass-by-value concept. – Yevgen Jul 31 '19 at 21:15
  • I have tried the similar code in debugger and this is what happens. Indeed a copy of a reference to an Integer object (your class field) is passed into the method. But since an Integer class is immutable and can hold only a single value - when you increment it - an unboxing happens and then it is boxed again, you can see in debugger how the new Integer object is created. – Yevgen Jul 31 '19 at 21:18
  • So the problem is boxing/unboxing specific, and since those wrappers were to provide wrapping, but not mutability, the identical behavior (compared to primitives) is achieved through constant unboxing and boxing (and this is why you loose the reference to the class field). I would love to see someone to provide a deeper coverage on this particular question. – Yevgen Jul 31 '19 at 21:33
  • @Podarkes "Deeper coverage" meaning what, exactly? There's nothing to add. *ahem* – Dave Newton Aug 01 '19 at 03:04
  • Awesome - thanks all for the additional info and the clarification. – jb62 Aug 01 '19 at 20:15

0 Answers0