How do I use an equivalent to C++ reference parame

2020-02-04 06:07发布

Suppose I have this in C++:

void test(int &i, int &j)
{
    ++i;
    ++j;
}

The values are altered inside the function and then used outside. How could I write a code that does the same in Java? I imagine I could return a class that encapsulates both values, but that seems really cumbersome.

11条回答
唯我独甜
2楼-- · 2020-02-04 06:48

Are the two integers related? Like a pair of x/y coordinates? If so, I would put the integers in a new class and pass that class into the method.

class A{ 
  public void test(Coord c)
  {
    c.x++;
    c.y++;
  }
  private class Coord{
    public int x, y;
  }
}

If the two integers are not related, you might want to think about why you are passing them into the same method in the first place.

查看更多
放我归山
3楼-- · 2020-02-04 06:51

Though its a bad design pattern IMHO, Another possible solution is

static void test(AtomicInteger i, AtomicInteger j)
{
    i.incrementAndGet();
    j.incrementAndGet();
}
查看更多
Bombasti
4楼-- · 2020-02-04 06:52

The easiest solution is to use org.apache.commons.lang.mutable.MutableInt class you don't need to write by yourself.

查看更多
对你真心纯属浪费
5楼-- · 2020-02-04 06:55

Simulating reference with wrappers.

One way you can have this behavior somehow simulated is create a generic wrapper.

public class _<E> {
    E ref;
    public _( E e ){
        ref = e;
    }
    public E g() { return ref; }
    public void s( E e ){ this.ref = e; }

    public String toString() {
        return ref.toString();
    }
}

I'm not too convinced about the value of this code, by I couldn't help it, I had to code it :)

So here it is.

The sample usage:

public class Test {

    public static void main ( String [] args ) {
        _<Integer> iByRef = new _<Integer>( 1 );
        addOne( iByRef );
        System.out.println( iByRef ); // prints 2

        _<String> sByRef = new _<String>( "Hola" );
        reverse( sByRef ); 
        System.out.println( sByRef ); // prints aloH

    }

    // Change the value of ref by adding 1
    public static void addOne( _<Integer> ref ) { 
        int i = ref.g();
        ref.s( ++i  );

        // or 
        //int i = ref.g();
        //ref.s( i + 1 );

    }
    // Reverse the vale of a string.
    public static void reverse( _<String> otherRef ) { 
        String v = otherRef.g();
        String reversed = new StringBuilder( v ).reverse().toString();
        otherRef.s( reversed );
    }

}

The amusing thing here, is the generic wrapper class name is "_" which is a valid class identifier. So a declaration reads:

For an integer:

_<Integer> iByRef = new _<Integer>( 1 );

For a String:

_<String> sByRef = new _<String>( "Hola" );

For any other class

_<Employee> employee = new _<Employee>( Employee.byId(123) );

The methods "s" and "g" stands for set and get :P

查看更多
手持菜刀,她持情操
6楼-- · 2020-02-04 07:02

You have to box it (your way) somehow.

Integer is immutable. so useless. int is mutable but since java is pass by value then its unusable again in that case. See these pages for more explanations: Java is Pass-by-Value, Dammit! and int vs Integer

Apache commons lang has a MutableInt class. Or you could write it yourself.

In any case, it should not be that bad because it should not happen often. If it does, then you should definitively change the way you code in Java.

查看更多
The star\"
7楼-- · 2020-02-04 07:05

You could construct boxed objects, ie,

Integer iObj = new Integer(i);
Integer jObj = new Integer(j);

and write your routine as

public void test(Integer i, Integer j){
  i = i.add(1);
  j = j.add(1);
}

For any number of reasons, the designers of Java felt call-by-value was better; they purposefully didn't include a method for call by reference. (Strictly, they pass copies of references to the objects, with the special case for the primitive types that they are purely call by value. But the effect is the same.)

查看更多
登录 后发表回答