Як повертаються кілька значень у Java?


11

Іноді потрібно повернути кілька значень функції. Як це зазвичай робиться на Java?

Один із варіантів - використовувати масив, як цей фрагмент Python, який повертає список або кортеж:

value, success = read_unreliably()
if success:
    print value

Іншим варіантом буде повернути хеш / дикт, як цей приклад JavaScript:

var result = readUnreliably()
if (result.success) {
    alert(value);
}

Ще одним було б створити спеціальний об’єкт саме для цієї мети, як цей приклад Java:

ReadUnreliablyResult result = readUnreliably()
if (result.getSuccess()) {
    System.out.println(result.getValue());
}

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


Чи справді "справжні" люди Java переживають проблеми використання публічних геттерів та сетерів, щоб сховати поля на таких маленьких внутрішніх класах? Просто цікаво.
Кріс Фармер

3
Так, більшість робить. Оскільки багато фреймворків очікують стандарту JavaBean, ви можете пошкодувати, що не маєте геттерів та сетерів. У будь-якому випадку, ваш IDE створить їх для вас.
Ерік Вілсон,

3
Або ви можете просто залишити їх на основі принципу YAGNI. Але це здається не так часто, як можна було очікувати.
MatrixFrog

@FarmBoy: Напевно, я розумію в зернах і тому подібному, але ОП означає, що це просто разовий клас, призначений для повернення кількох значень.
Кріс Фармер

@ChrisFarmer Я думаю, що в цьому контексті я ніколи не бачив, щоб "справжній" Java-програміст створив для цього клас.
Ерік Вілсон

Відповіді:


26

Як це зазвичай робиться на Java?

Болісно.

Один з варіантів - використовувати масив, як цей фрагмент Python, який повертає список або кортеж ...

Іншим варіантом буде повернути хеш / дикт, як цей приклад JavaScript ...

Ці методи не працюють добре на Java; значення повинні були бути відхилені від Object.

Ще одним було б створити спеціальний об’єкт саме для цієї мети, як цей приклад Java ...

Це найчастіше, але створювати всі ті маленькі класи досить складно. У C ++ звичайно використовувати std :: pair, але це не часто робиться в Java.

З Lombok легко створити невеликі спеціальні об'єкти:

@RequiredArgsConstructor
public class X {
  private final boolean status;
  private final byte[] data;

}


10
"Як це зазвичай робиться на Java?" "Болісно". LOL як розробник Java, я повинен поставити вам +1 за це
TheLQ,

Використання компактного незмінного структури, схожого на структуру, не так болісно ... Це справді як написання структури C ...
Гійом

1
@Guillaume - точно, але всі ці дрібниці складаються як у часі, так і в просторі. Я не знаю, чому спільнота Java не прийняла стандартний набір дженериків, таких як "Клас Пара <T1, T2> {public T1 перший; public T2 second; ...}"; в сучасних мовах ви просто "повертаєте a, b"; а потім напишіть "x, y = f ()";
кевін клайн

1
Я впевнений, що деякі "стародавні" мови також здатні це зробити :) IMHO Я знайшов, що декілька значень повернення можуть призвести до загального безладу, і якщо вам потрібно додати інші поля повернення, вам просто потрібно оновити структуру, як клас, не змінити підпис методу.
Гійом

1
Що "Болісно". мене сильно вразило, так, саме це я відчуваю як розробник Java, коли зустрічаюся з подібними ситуаціями.
artjom

13

Так, спосіб створення а struct/ tuple/ recordв Java - це створення класу. Якщо це лише для внутрішнього використання, я вважаю за краще використовувати невеликий незмінний структурно-подібний клас із публічними полями.

Приклади:

public class Unreliably {
    public final boolean success;
    public final int value;
    public Unreliably(boolean success, int value) {
        this.success = success; this.value = value;
    }
}

Це набагато простіше зробити в Scala:

case class Unreliably(success: Boolean, value: Int)

8
Насправді, у Scala ви, мабуть, взагалі просто повернете Tuple2[Boolean, Int]. Хоча в цьому конкретному прикладі ви повернете Option[Int].
Йорг W Міттаг

2
Таким чином, це відповідає на питання Кріса Фармера (у коментарях Q) про те, що справжні люди на Яві не обов'язково створюють геттери та сетери для маленьких внутрішніх класів. Ви "справжня" людина Яви, правда?
Майк М. Лін

2
Іншими новинами немає справжніх шотландців.
Джозеф Вайсман

5

Для прикладу, який ви навели, кидання винятку було б найстандартнішим способом впоратися з ним:

try {
    result = readUnreliably();
    System.out.println(result);
} (catch IOException e) {
    System.out.println("Could not read file");
}

Більше того, якщо ви прагнете мати функції, які "роблять одну річ", функція повернення декількох значень є менш необхідною, хоча іноді зручною.


4

У нас є загальний клас Pair, який може зберігати один екземпляр A і один екземпляр B. Ви, ймовірно, можете створити Triplet або Quadruplet таким же чином.

public class Pair<A, B>
{
    ...
}

1
це робить для деяких дійсно нечитабельним код. якщо метод повертається Pair<String, Integer>, що це означає? що представляють ці значення? ви, можливо, не можете знати, не прочитавши впровадження методу.
сара

1

У Java ваша функція повертає об'єкт (або, можливо, нуль у разі відмови). Таким чином можна повернути кілька фрагментів даних.


1

Немає явного способу повернення декількох змінних на Java, проте є кілька підходів:

  1. Перший - пройти шлях масиву. Це справді працює лише в тому випадку, якщо у вас є все як один і той же тип даних або ви можете тимчасово перетворити їх в один тип.
  2. Другий спосіб - створити клас з метою передачі декількох типів змінних. У своїй роботі ми називаємо це DTO або Об'єктами передачі даних.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.