例如,我想创建一个可以返回任何数字(负数,零或正数)的函数。
但是,根据某些例外情况,我希望函数返回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's 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's just have this function throw an exception and
say the coefficients are invalid
*/
}
return (-b + Math.sqrt(x) * polarity) / (2*a);
}
}
答案 0 :(得分:13)
不,你不能用Java做到这一点。
你可以返回Object
。通过返回一个对象,您可以在技术上返回一个派生类,例如java.lang.Integer
或java.lang.Boolean
。但是,我认为这不是最好的主意。
答案 1 :(得分:11)
你可以从技术上做到这一点:
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需要评估您对异常处理的使用。如果您可以对该异常执行某些操作(即恢复,保留,重试等),则会在特殊情况下捕获异常。例外是预期工作流程的例外,而不是其中的一部分。
答案 2 :(得分:6)
没有。你可以做的最好的事情是返回一个类的实例,它处理你可能想要返回的所有东西。
类似
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,具体取决于限定条件。
答案 3 :(得分:4)
大多数语言都会处理您的特定示例而没有Exceptions或union类型,因为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);
}
以下是您的Exception的客户端代码。
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());
}
要真正向方法传递或返回不相关的类型,您需要Java不支持的Union类型。但是Paguro提供了Union Types,您可以像这样使用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));
}
对于您的具体示例,只需使用浮点。对于更通用的解决方案,我发现union类型比Exceptions更有用。您可以使用union类型作为方法的参数,该方法可能需要两个不同的输入,这些输入没有公共接口或祖先。他们对功能编程也更友好。
答案 4 :(得分:3)
编写一个返回Object
的函数。让它返回Boolean
或Integer
包装器对象。然后使用instanceof找出要使用的内容。
答案 5 :(得分:1)
不,一个返回对客户的引用。
您可以编写一个响应对象,它将boolean和int封装在一起,并根据您的心血来潮设置值。
但如果我是用户,我认为你的设计令人困惑。
答案 6 :(得分:1)
我的老师对java中的tryParse C#方法有一个很酷的想法,希望它有所帮助
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;
}
}
}
答案 7 :(得分:0)
这可能不是最佳解决方案,具体取决于您想要做什么,但解决问题的简单方法可能是让函数返回一个int或一个超出可能范围的常量(例如RETURNED_FALSE / TRUE)和检查一下。
答案 8 :(得分:0)
绝对!在您的情况下,由于返回值可以为正,0,负或假,因此最好的返回值可能是JSONObject。在您的代码中,您将添加以下导入:
import org.json.JSONObject;
并在函数中:
JSONObject retval = new JSONObject();
double x = b*b - 4*a*c;
if(x < 0){
retval.put("result", false);
}
else{
retval.put("result", x);
}
您还可以在retval中添加另一个key:value对,以包括结果类型,以帮助在调用函数中对其进行检查。
答案 9 :(得分:-1)
我会说这是可能的。但不是直接的。
我还没有通过问题中给出的程序。知道这是一篇旧帖,我正在回答这个问题。可以帮助别人。
将您的值添加到如下所示的地图中。用钥匙拿它!
public static HashMap returnAnyType(){
String x = "This";
int a = 9;
HashMap<String, Object> 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: " + Math.addExact(theIntFromTheMap, 10));
输出(两者都是从同一方法返回):
String : This is great! Integer: 19
注意:
这不是一个好习惯。但有时需要时会有所帮助!
答案 10 :(得分:-2)
inout参数仅适用于可以变异的对象。对于String inout参数,传入StringBuilders而不是String,然后替换()它们的值。