Блог пользователя dreamplay

Автор dreamplay, история, 7 лет назад, По-английски

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

  • Проголосовать: нравится
  • -3
  • Проголосовать: не нравится

»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

»
7 лет назад, # |
  Проголосовать: нравится +20 Проголосовать: не нравится

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

»
7 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

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 лет назад, # ^ |
    Rev. 4   Проголосовать: нравится +6 Проголосовать: не нравится

    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 лет назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится
      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 лет назад, # ^ |
        Rev. 3   Проголосовать: нравится +6 Проголосовать: не нравится

        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 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

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

»
7 лет назад, # |
  Проголосовать: нравится -8 Проголосовать: не нравится

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

»
7 лет назад, # |
Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

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 лет назад, # |
Rev. 3   Проголосовать: нравится +16 Проголосовать: не нравится

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]++;
    }
}