dreamplay's blog

By dreamplay, history, 7 years ago, In English

I recently started learning basics of Java and got stuck on this doubt. How to write Java code for the below given C++ code. Note that making a class and passing an object or returning some object looks like a hack to me. So looking for other possible answers.

// c++ code
void f(int & x, int & y) {
    x++;y++;
}
f(x, y); // function call somewhere

Thanks

  • Vote: I like it
  • -3
  • Vote: I do not like it

»
7 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by dreamplay (previous revision, new revision, compare).

»
7 years ago, # |
  Vote: I like it +20 Vote: I do not like it

You can't, Java doesn't pass method arguments by reference; it passes them by value.

»
7 years ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Things like ints, longs, doubles, strings, Integer, Long, etc. are immutable in Java. So when you pass these types as arguments, they pass by value and not reference. If you did the same thing with a list or queue (mutable objects) they pass by reference and would reflect changes made in the function.

I haven't really seen a way to get past this without the hack you mentioned.

  • »
    »
    7 years ago, # ^ |
    Rev. 4   Vote: I like it +6 Vote: I do not like it

    Everything is passed by value (not by reference). Or better said, everything is a reference and all references are passed by value. Queues are also passed by value (and not by reference). The code below will get you a NullPointerException.

    public static void main(String[] args) {
        Queue<Integer> q = null;
        alloc(q);
        System.out.println(q.size());
    }
    
    
    public static void alloc(Queue<Integer> q){
        q = new ArrayDeque<>();
    }
    
    • »
      »
      »
      7 years ago, # ^ |
        Vote: I like it +1 Vote: I do not like it
      public static void main(String[] args) {
      		Queue<Integer> q = null;
      		q = new ArrayDeque<>();
      		alloc(q);
      		System.out.println(q.size());
      	}
      
      
      	public static void alloc(Queue<Integer> q){
      //		q = new ArrayDeque<>();
      		q.add(10);
      	}
      

      But if you ran this code then q.size() is 1. Isn't that passing by reference then and not value?

      • »
        »
        »
        »
        7 years ago, # ^ |
        Rev. 3   Vote: I like it +6 Vote: I do not like it

        It is still by value (only the references are passed). You will have two references (q and some temporary reference than is created by the compiler) that are equal to each other (they point to the same object).

        My example is better at showing this fact. You get a NullPointerException because the temporary reference is pointed to a new ArrayDeque while the original one (q) is still left to point to null.

        • »
          »
          »
          »
          »
          7 years ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          Okay yeah that makes sense. Thanks!

  • »
    »
    7 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    We have Integer class in java which is not a primitive i suppose. Sadly in this case it doesn't help directly as Integer++ won't work due to some well apparently known reasons.

    • »
      »
      »
      7 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      According to Stack Overflow Integer was made immutable for design reasons. Which sounds kinda silly but whatever.

»
7 years ago, # |
  Vote: I like it -8 Vote: I do not like it

public static void binsearch(long n,long m) ,this a part from my code ,maybe it will be useful.

»
7 years ago, # |
Rev. 3   Vote: I like it 0 Vote: I do not like it

Short answer: It is NOT possible.

Longer answer: There is (another) hack. You don't create any new classes, so this is not a hack by your definition. But you still need one that uses synchronization which is kinda worse in my opinion. I'll let you be the judge of that.

Note: You should never use AtomicInteger in this way.

import java.util.concurrent.atomic.AtomicInteger;

public class Main {

    public static void main(String[] args) {
        AtomicInteger x = new AtomicInteger(10);
        AtomicInteger y = new AtomicInteger(20);
        f(x, y);
        System.out.println(x + " " + y);
    }

    public static void f(AtomicInteger x, AtomicInteger y){
        x.incrementAndGet();
        y.incrementAndGet();
    }
}
»
7 years ago, # |
Rev. 3   Vote: I like it +16 Vote: I do not like it

Hacky, but it works.

public class Main {
    public static void main(String[] args) {
        int[] x = { 1 };
        int[] y = { 2 };
        f(x, y);
    }
    public static void f(int[] x, int[] y) {
        x[0]++;y[0]++;
    }
}