Как написать функцию Java, которая возвращает значения нескольких типов данных?

Например, я хочу создать функцию, которая может возвращать любое число (отрицательное, ноль или положительное).

Однако, основываясь на некоторых исключениях, я хотел бы вернуть функцию Boolean FALSE

Есть ли способ написать функцию, которая может вернуть int или a Boolean?


Хорошо, так что это получило много ответов. Я понимаю, что я просто неправильно подхожу к проблеме, и я должен throw выполнить какое-то исключение в методе. Чтобы получить лучший ответ, я приведу примерный код. Пожалуйста, не развлекайтесь:)

public class Quad {

  public static void main (String[] args) {

    double a, b, c;

    a=1; b=-7; c=12;
    System.out.println("x = " + quadratic(a, b, c, 1));   // x = 4.0
    System.out.println("x = " + quadratic(a, b, c, -1));  // x = 3.0


    // "invalid" coefficients. Let throw an exception here. How do we handle the exception?
    a=4; b=4; c=16;
    System.out.println("x = " + quadratic(a, b, c, 1));   // x = NaN
    System.out.println("x = " + quadratic(a, b, c, -1));  // x = NaN

  }

  public static double quadratic(double a, double b, double c, int polarity) {

    double x = b*b - 4*a*c;

    // When x < 0, Math.sqrt(x) retruns NaN
    if (x < 0) {
      /*
        throw exception!
        I understand this code can be adjusted to accommodate 
        imaginary numbers, but for the sake of this example,
        let just have this function throw an exception and
        say the coefficients are invalid
      */
    }

    return (-b + Math.sqrt(x) * polarity) / (2*a);

  }

}

Ответы

Ответ 1

Нет, вы не можете сделать это на Java.

Вы можете вернуть Object. И возвращая объект, вы можете технически вернуть производный класс, такой как java.lang.Integer или java.lang.Boolean. Однако я не думаю, что это лучшая идея.

Ответ 2

Вы можете технически сделать это:

public <T> T doWork()
{
   if(codition)
   {
      return (T) new Integer(1);
   }
   else
   {
      return (T) Boolean.FALSE;
   }
}

Затем этот код будет скомпилирован:

int x = doWork(); // the condition evaluates to true
boolean test = doWork();

Но вы наверняка столкнетесь с исключениями времени выполнения, если метод возвращает неправильный тип. Вы также должны возвращать объекты вместо примитивов, потому что T стирается в java.lang.Object, что означает, что возвращаемый тип должен расширять Object (т.е. Быть объектом). В приведенном выше примере используется автобоксинг для получения примитивного типа возврата.

Я, конечно, не рекомендовал бы этот подход, потому что IMO вам нужно оценить ваше использование обработки исключений. Вы исключаете исключения в исключительных случаях, если можете что-то сделать с этим исключением (например, восстановить, продолжить, повторить попытку и т.д.). Исключения являются исключением из ожидаемого рабочего процесса, а не его частью.

Ответ 3

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

что-то вроде

public class ReturnObj {
   public bool yesno; // yes or no
   public int val; // for int values
   public String mode; // mode describing what you returned, which the caller will need to understand.
}

очевидно, вам нужно играть с именами....

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

Ответ 4

Напишите функцию, которая возвращает Object. Попросите его вернуть объекты оболочки Boolean или Integer. Затем используйте instanceof, чтобы выяснить, что использовать.

Ответ 5

Плавающая точка IEEE

Большинство языков будут обрабатывать ваш конкретный пример без исключений или типов объединения, поскольку плавающая точка IEEE включает представление для NaN. В Java используйте Double.NaN:

public static double quadratic(double a, double b, double c, int polarity) {
    double x = b*b - 4*a*c;

    // When x < 0, Math.sqrt(x) retruns NaN
    if (x < 0) {
        return Double.NaN;
    }
    return (-b + Math.sqrt(x) * polarity) / (2*a);
}

Это дает ваш точный результат, который вы хотели:

x = 4.0
x = 3.0
x = NaN
x = NaN

Исключения

Исключения - это старый способ Java для решения подобных проблем:

public static double quadratic(double a, double b, double c, int polarity) {
    double x = b*b - 4*a*c;
    // When x < 0, Math.sqrt(x) returns NaN
    if (x < 0) {
        throw new Exception("NaN")
    }
    return (-b + Math.sqrt(x) * polarity) / (2*a);
}

Вот ваш код клиента для исключения.

a=1; b=-7; c=12;

// x = 4.0
try {
    System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
    System.out.println("Oopsie: " + iae.getMessage());
}

// x = 3.0
try {
    System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
    System.out.println("Oopsie: " + iae.getMessage());
}

// "invalid" coefficients.
a=4; b=4; c=16;

// Oopsie: NaN
try {
    System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
    System.out.println("Oopsie: " + iae.getMessage());
}

// Oopsie: NaN
try {
    System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
    System.out.println("Oopsie: " + iae.getMessage());
}

Типы соединений

Чтобы действительно передавать или возвращать несвязанные типы в метод или из него, вы хотите, чтобы типы Union, которые Java действительно не поддерживают. Но Paguro предоставляет Типы соединений, которые вы можете использовать в Java, как это (используя Or):

public static Or<Double,String> quadratic(double a, double b,
                                          double c, int polarity) {
    double x = b*b - 4*a*c;

    // When x < 0, Math.sqrt(x) retruns NaN
    if (x < 0) {
        return Or.bad("NaN");
    }
    return Or.good((-b + Math.sqrt(x) * polarity) / (2*a));
}

@Test public void testQuadradic() {
    double a, b, c;
    a=1; b=-7; c=12;

    // x = Good(4.0)
    System.out.println("x = " + quadratic(a, b, c, 1));

    // x = 3.0
    System.out.println(
            (String) quadratic(a, b, c, -1)
                    .match(good -> "x = " + good,
                           bad -> "Oopsie: " + bad));

    // "invalid" coefficients.
    a=4; b=4; c=16;

    // x = Bad("NaN")
    System.out.println("x = " + quadratic(a, b, c, 1));

    // Oopsie: NaN
    System.out.println(
            (String) quadratic(a, b, c, -1)
                    .match(good -> "x = " + good,
                           bad -> "Oopsie: " + bad));
}

Заключение

В вашем конкретном примере просто используйте Floating Point. Для более общего решения я нахожу типы объединения более полезными, чем Исключения. Вы можете использовать типы union в качестве аргументов метода, который может принимать два разных входа, которые не имеют общего интерфейса или предка. Они также более дружелюбны к функциональному программированию.

Ответ 6

Нет, одна обратная ссылка на клиента.

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

Но если бы я был пользователем, я бы подумал, что ваш дизайн запутан.

Ответ 7

У моего учителя была отличная идея для метода tryParse С# в java, надеюсь, что он помогает

import java.util.Scanner;

public class Program {
    static Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) {
        System.out.println("Enter number");
        String input = scanner.next();
        int[] num ={0};
        if(tryParse(input,num))
            System.out.println(num[0] * num[0]);
    }
    static boolean tryParse(String inputString,int[] outputInt){
        try{
            outputInt[0] = Integer.parseInt(inputString);
            return true;
        }catch(Exception e){
            return false;
        }
    }
}

Ответ 8

Это может быть не лучшее решение в зависимости от того, что вы хотите сделать, но простой способ решить проблему может состоять в том, чтобы функция возвращала int или константу за пределами возможного диапазона (например, RETURNED_FALSE/TRUE) и проверьте это.

Ответ 9

Я бы сказал, что это возможно. Но не напрямую.

Я не прошел через программу, заданную в вопросе. Я отвечаю на это, зная, что это старый пост. Может помочь кому-то.

Добавьте свои значения на карту, как показано ниже. И получите его своим ключом!

public static HashMap returnAnyType(){
    String x = "This";
    int a = 9;

    HashMap myMap = new HashMap();
    myMap.put("stringVal", x);
    myMap.put("intVal", a);
    return myMap;
}

String theStringFromTheMap = (String) returnAnyType().get("stringVal");
int theIntFromTheMap = (Integer) returnAnyType().get("intVal");

System.out.println("String : " + theStringFromTheMap + " is great !");   
System.out.println("Integer: " + theIntFromTheMap + 10);

Вывод (оба возвращаются из того же метода):

String : This is great!
Integer: 19

Примечание:
Это не очень хорошая практика. Но иногда это помогает, когда это необходимо!

Ответ 10

inout параметры работают только для объектов, которые могут быть изменены. Для параметров String inout передайте в StringBuilders вместо строк, затем замените() их значения.