Как создать параметры IN OUT или OUT в Java - PullRequest
8 голосов
/ 16 декабря 2010

В PL / SQL (или многих других языках) я могу иметь параметры IN OUT или OUT, которые возвращаются из процедуры. Как я могу добиться подобного в Java?

Я знаю этот трюк:

public void method(String in, String[] inOut, String[] inOut2) {
  inOut[0] = in;
}

Где параметр in представляет параметр IN, а параметр inOut может содержать возвращаемое значение. Соглашение было бы, что String[] inOut является массивом inOut.length == 1.

Это немного неуклюже.

РЕДАКТИРОВАТЬ Обратная связь к ответам : Другие хитрости включают в себя:

  • классы владельца / оболочки, но я не хочу вводить какие-либо новые типы, обратные вызовы и т. Д.
  • возвращаемые значения: я бы хотел общее решение. То есть один с несколькими параметрами IN OUT.
  • обертка для параметра IN OUT в качестве возвращаемого значения: это жизнеспособная опция, но все же не очень хорошая, потому что эту обертку нужно будет как-то сгенерировать

Кто-нибудь знает лучший способ добиться этого вообще? Причина, по которой мне нужно общее решение, заключается в том, что я хочу сгенерировать удобный исходный код из PL / SQL в схеме базы данных.

Ответы [ 3 ]

10 голосов
/ 16 декабря 2010

Мой вопрос будет таким: Почему method не возвращает что-то?Вместо того, чтобы задавать аргумент in / out?

Но если вы абсолютно точно абсолютно уверены, что должен иметь аргумент in / out, что является совершенно другим вопросом, тогда трюк с массивами подойдет.С другой стороны, это не менее неуклюже, но другой способ - передать ссылку на объект:

public class Foo {
    private String value;

    public Foo(String v) {
        this.value = v;
    }

    public String getValue() {
        return this.value;
    }

    public void setValue(String v) {
        this.value = v;
    }
 }

 // ....
 public void method(String in, Foo inOut) {
     inOut.setValue(in);
 }

(или, конечно, просто сделать value общедоступным.) Видите?Я сказал, что это не менее неуклюже.

Но я бы снова спросил: не может method вернуть что-нибудь?И если ему нужно вернуть несколько вещей, не может ли он вернуть экземпляр объекта со свойствами для этих вещей?

Не по теме: Это одна из областей, где мне действительно нравитсяC # подход.Один из аргументов против аргументов in / out заключается в том, что они неясны в тот момент, когда вы вызываете функцию.Таким образом, C # делает это понятным, указав ключевое слово при объявлении функции и при ее вызове.В отсутствие такой синтаксической помощи я бы избегал «симуляции» аргументов in / out.

4 голосов
/ 16 декабря 2010

Java копирует все, что вы передаете в качестве аргумента. Если вы передаете примитив, внутри метода у вас есть копия этого примитива, и никакие изменения не повлияют на фактическую переменную вне метода. Если вы передаете объект, вы передаете копию ссылки, которая фактически ссылается на исходный объект. Это способ, которым вы можете распространять изменения в контексте чего-то, что вызвало метод - путем изменения состояния объекта, на который «указывает» ссылка. Подробнее об этом: Передает ли Java по значению или по ссылке?

1 голос
/ 16 декабря 2010

Прямого пути нет. Другая техника включает в себя:

  • Передача объекта-держателя (немного похоже на ваш 1-рядный массив)
  • Использование, например, AtomicInteger
  • Передача более полезного объекта с точки зрения бизнеса, который оказывается изменчивым
  • Обратный вызов пользовательского интерфейса для получения результата

Если подумать, трюк с массивом не отличается от передачи T * в C / C ++

...