5

I realize this is probably a really basic question, but I can't figure it out.

Say I have this main class

public class Main{

    public static void main(String[] args){
        int a = 0;
        AddSomething.addOne(a);
        System.out.println("Value of a is: "+String.valueOf(a));
    }
}

Here is AddSomething class and addOne() method

public class AddSomething{

    public static void addOne(int a){

        a++;

    }
}

The addOne method is not adding anything

System.out.println("Value of a is: "+String.valueOf(a));
// Prints 0 not 1

How can I make Add class update variable a in Main class?

Ed Carrel
  • 4,154
  • 1
  • 25
  • 17
the_prole
  • 8,275
  • 16
  • 78
  • 163
  • Java is [call-by-value](http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value). – Seelenvirtuose Nov 27 '15 at 07:30
  • 1
    check http://stackoverflow.com/questions/3330864/how-can-i-pass-an-integer-class-correctly-by-reference – hemu Nov 27 '15 at 07:30
  • Although someone give you an alternative method to do what you want, but it's not actually add one to a, it assign an new value to a. So I suggest you to read some book that introduce JAVA and see what JAVA's Object and primitive types are passing during function call. – Roger Dwan Nov 27 '15 at 07:33
  • Maybe this post can help you understand better what is happening : http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value. Java is "pass by value" and I think it is an important thing to understand. – Mathias Aboudou Nov 27 '15 at 07:35

3 Answers3

6

addOne receives a copy of a, so it can't change the a variable of your main method.

The only way to change that variable is to return a value from the method and assign it back to a:

a = Add.addOne(a);

...

public int addOne(int a){
    return ++a;
}
Eran
  • 387,369
  • 54
  • 702
  • 768
  • This is true for a static method. For completeness, it would be better to explain what problems this may cause and what are alternatives (ie. creating instance etc.) – ouzture Nov 27 '15 at 07:32
  • So there is no way to pass the object without making a new copy? I thought I could get around this using static classes somehow. – the_prole Nov 27 '15 at 07:36
  • @the_prole You can pass to `addOne` an instance of a class having an int property, and `addOne` would be able to mutate the int property of that instance. – Eran Nov 27 '15 at 07:39
  • @Eran so primitive types pass by value, but instances pass by reference? – the_prole Nov 27 '15 at 07:41
  • @the_prole Both are pass by value, but for reference types (i.e. variables the refer to instances of classes), if they refer to a mutable object, you can change the state of that object inside the method. You can't change the reference itself to refer to a different object. – Eran Nov 27 '15 at 07:44
  • @Eran Okay I understand now, but can't primitive types have references also? – the_prole Nov 27 '15 at 07:55
  • @the_prole No. There are wrapper classes that wrap primitive type (for example Integer wrap int), but these classes are immutable, so even if you pass such a wrapper class instance to a method, the method can't change the primitive value it contains. – Eran Nov 27 '15 at 07:57
  • @Eran So that fact that I declare a variable say "int a = 3" does not mean that "a" is a reference? – the_prole Nov 27 '15 at 08:07
  • Isn't it supposed to be `a++` instead of `++a` as in the question? – Jonathan Doe Aug 03 '17 at 08:17
  • @JonathanDoe if you return `a++` and assign the result back to `a`, `a` will never change, since the post increment operator returns the original value of `a`. – Eran Aug 03 '17 at 08:19
  • Okay. So, what's the difference between a++ (a = a + 1) and ++a? – Jonathan Doe Aug 03 '17 at 08:26
  • @JonathanDoe The return value of ++a (pre increment operator) is a+1. – Eran Aug 03 '17 at 08:28
  • I mean what is `++a` short for? `a++` is short for `a = a + 1` Thanks for the help! – Jonathan Doe Aug 03 '17 at 08:34
  • @JonathanDoe Both ++a and a++ increment the value of a, but they return a different value. `System.out.println(a++)` and `System.out.println(++a)` will print different values. Google post increment and pre increment operators. – Eran Aug 03 '17 at 08:37
2

Thats becouse primitive types in java pass to methods by value. Only one way to do what you want is reassign variable, like :

public class Main{

    public static void main(String[] args){
        int a = 0;
        a = Add.addOne(a);
        System.out.println("Value of a is: "+String.valueOf(a));
    }
}

and

public class AddSomething{

    public static int addOne(int a){

    return a++;

    }
}
midikko
  • 146
  • 11
  • I see, so primitive type pass by value. How about ArrayLists? – the_prole Nov 27 '15 at 07:40
  • 1
    @the_prole it's an object, so it's will pass-by-reference. Yep. You can modify it. – midikko Nov 27 '15 at 07:44
  • Beware that it is a bit tricky to say "by value" or "by reference". Technically everything is passed "by value". In case of objects the value is the reference value, i.e. the object address in memory. This is important to understand, because you can't change the object, i.e. you can't replace your ArrayList (that came as a method parameter) with another ArrayList, you can only mutate the object via its methods, for example, ArrayList.add(). – Ruslan Apr 03 '17 at 14:25
-1

I know, Eran's answer is what you all need. But just to show another way, posting this answer.

public class Main
{
  static int a = 0;
  public static void main(String[] args)
  {
    AddSomething.addOne();
    System.out.println("Value of a is: "+a);
  }
}

And in AddSomething class..

public class AddSomething
{
    public static void addOne(){ Main.a++ };
}

AddSomething must be in same package as Main class, as int a has default access modifier.

Akoder
  • 147
  • 6