Передача примитивных типов как параметров в Java - PullRequest
6 голосов
/ 08 февраля 2010

Мне нужно возвращать / обновлять логическое значение при возврате списка вещей из метода. Java не может возвращать кортежи, и я не хотел создавать отдельный класс для этого, поэтому решил, что я передам bool как выходной параметр. Это то, что делает наш клиент C ++, передает bool по ссылке. Это сработало бы для нормального класса, так как java-тип имеет pass-by-ref для объектов (см. Является ли Java "pass-by-reference" или "pass-by-value"? для хорошего обсуждения этот). Но классы Wrapper, такие как Boolean, сохраняют свое примитивное значение неизменным, поэтому его нельзя обновить таким образом.

Использование логического массива (с одной записью) выглядит нелепо, но, пожалуй, самое простое, что работает. В качестве альтернативы, может вернуть логическое значение и передать созданный список обратно как выходной параметр, а не как возвращение [но тогда java-клиент отклоняется от C ++, и лучше всего, если они придерживаются в основном того же подхода - к сведению, это нужно и в C #. ]

Ответы [ 6 ]

14 голосов
/ 08 февраля 2010

Нет, в Java нет передачи по объектам; у него есть «передать ссылку по значению», что не то же самое.

Вы определенно не можете передавать что-либо как параметр "out" или по ссылке в Java - хотя вы могли бы это сделать в C #.

Не могли бы вы инкапсулировать "Булев плюс список" в другой тип? Они на самом деле связаны? Использование логического массива определенно довольно уродливо. Вы могли бы написать MutableBoolean тип оболочки - но опять же, это довольно уродливо. Обычно я бы сказал, что возвращение двух вещей предполагает, что метод должен быть разделен, но когда один из них является логическим, он может быть довольно разумным - как int.TryParse и т. Д. Из C #.

7 голосов
/ 08 февраля 2010

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

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

Вы можете решить эту проблему, создав собственный изменяемый логический тип и передав ссылку на него, что-то вроде:

public class Example {
    public class BooleanResult {
        private boolean result;

        public void setResult(boolean value) { result = value; }
        public boolean getResult() { return result; }
    }

    // ....
    public List doSomething(BooleanResult out) {
        List list;
        boolean result;

        // ...

        out.setResult(result);

        return list;
    }
}

и используйте его как:

Example.BooleanResult out = new Example.BooleanResult();

List list = example.doSomething(out);

boolean result = out.getResult();
4 голосов
/ 10 февраля 2010

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

Я столкнулся с той же проблемой, и лучшее решение, как правило, ИМХО:

Просто забудь о своих заботах и ​​сделай отдельный урок.

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

Скорее всего, когда ваша функция вернет экземпляр пользовательского класса, вы обнаружите, что есть дополнительные функциональные возможности, которые хорошо вписываются в этот класс, или другие методы, которые могут использовать этот класс в качестве параметра или возвращаемого значения, и вскоре класс будет довольно полезен: -).

Если вы действительно не хотите этого делать, вы всегда можете поместить все в java.util.List или java.util.Map и вернуть это. Но это действительно ужасно :-( Я тоже так поступил и пожалел об этом. Поначалу это может показаться простым, но по мере развития и роста кода ухудшается читаемость (это был список целых чисел, затем двойник или наоборот?). Занятия гораздо полезнее.

Примечание. Если вы чувствуете, что обычный класс верхнего уровня является избыточным, вы можете использовать вложенный класс , который подходит только для классов "локального использования".

1 голос
/ 12 мая 2013

Вы не можете использовать ни один из примитивных типов в качестве параметра out в Java. Это просто не произойдет в любое время.

Вы также не можете использовать любые версии объектов, такие как Boolean, Integer, Float, Double и т. Д., В качестве параметров «out», поскольку они являются неизменяемыми. Что вы можете сделать, так это написать свой собственный класс или использовать что-то вроде MutableBoolean в commons-lang (http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/mutable/MutableBoolean.html).

Например:

public void setTrue(MutableBoolean b) {
    b.setValue(Boolean.TRUE);
}
1 голос
/ 08 февраля 2010

Что я сделал, чтобы вернуть несколько значений, так это изменить тип возвращаемого значения для возврата массива объектов.[0] может быть bool, а [1] может быть списком.

Недостатком является то, что вызывающая сторона должна знать, как правильно привести возвращаемые объекты из массива объектов, а компилятор не может проверитьyou.

Редактировать: Здесь - это SO-ответ для возврата пары значений из Java.

0 голосов
/ 20 августа 2013

Как упоминалось в rsp и многих других, оно неизменно. Тем не менее, существует логический вариант, называемый AtomicBoolean , который был представлен как часть java.util.concurrent.atomic в Java версии 1.5. Если вы не хотите создавать классы для обработки таких тривиальных проблем, AtomicBoolean - это то, что вам нужно. Проверьте это. Запустите следующий код, чтобы убедиться в этом.

public static void main(String[] args) {
    AtomicBoolean value = new AtomicBoolean(false);
    System.out.println(value); // Prints false
    someMethod(value);
    System.out.println(value); // Prints true
}

void someMethod(AtomicBoolean a) {
    a.set(true);
}
...