Как использовать эквивалентные ссылочные параметры C ++ в Java? - PullRequest
4 голосов
/ 10 января 2009

Предположим, у меня есть это в C ++:

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

Значения изменяются внутри функции, а затем используются снаружи. Как я мог написать код, который делает то же самое в Java? Я предполагаю, что мог бы вернуть класс, который инкапсулирует оба значения, но это кажется действительно громоздким

Ответы [ 11 ]

18 голосов
/ 10 января 2009

Имитация ссылки с обертками.

Один из способов имитировать это поведение - создать универсальную оболочку.

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();
    }
}

Я не слишком убежден в ценности этого кода, потому что я ничего не мог с этим поделать, мне пришлось его кодировать :)

Итак, вот оно.

Пример использования:

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 );
    }

}

Забавно, что общее имя класса-обертки - "_", которое является допустимым идентификатором класса. Итак, объявление гласит:

Для целого числа:

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

Для строки:

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

Для любого другого класса

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

Методы "s" и "g" означают set и get: P

13 голосов
/ 10 января 2009

Java не имеет эквивалента ссылок на C ++. Единственный способ заставить это работать - это инкапсулировать значения в другом классе и поменять их местами.

Вот длинное обсуждение вопроса: http://www.yoda.arachsys.com/java/passing.html

7 голосов
/ 10 января 2009

У Java нет передачи по ссылке. Вы должны заключить в капсулу для достижения желаемой функциональности. У Джона Скита есть краткое объяснение , почему передача по ссылке была исключена из Java.

6 голосов
/ 10 января 2009

Ну, есть несколько обходных путей. Вы упомянули один самостоятельно. Еще один будет:

public void test(int[] values) {
    ++values[0];
    ++values[1];
}

Я бы пошел с пользовательским объектом, хотя. Это намного чище. Также попробуйте перестроить проблему так, чтобы одному методу не нужно было возвращать два значения.

4 голосов
/ 10 января 2009

Лучший вопрос: почему вы создаете методы с такими побочными эффектами?

Как правило, это явный признак того, что вы должны извлекать данные в отдельный класс с общедоступными средствами доступа, которые описывают, почему выполняется операция.

0 голосов
/ 14 февраля 2015

Java передает параметры по значению и не имеет механизма, разрешающего передачу по ссылке.

0 голосов
/ 29 ноября 2012

Самое простое решение - использовать org.apache.commons.lang.mutable.MutableInt класс, который вам не нужно писать самостоятельно.

0 голосов
/ 23 января 2009

Хотя это плохой шаблон дизайна ИМХО, Другое возможное решение -

static void test(AtomicInteger i, AtomicInteger j)
{
    i.incrementAndGet();
    j.incrementAndGet();
}
0 голосов
/ 11 января 2009

Связаны ли два целых числа? Как пара координат х / у? Если это так, я бы поместил целые числа в новый класс и передал этот класс в метод.

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

Если два целых числа не связаны, вы можете подумать, почему вы в первую очередь передаете их в один и тот же метод.

0 голосов
/ 10 января 2009

Вы должны как-то его упаковать (по-своему).

Целое число является неизменным. так бесполезно. int является изменяемым, но поскольку java передается по значению, то в этом случае его снова невозможно использовать. Смотрите эти страницы для более подробного объяснения: Java - передача по значению, черт!

Apache commons lang имеет класс MutableInt. Или ты мог бы написать это сам.

В любом случае, это не должно быть так плохо, потому что это не должно случаться часто. Если это так, то вам следует окончательно изменить способ кодирования в Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...