如何编写返回多种数据类型值的Java函数?
例如,我想创建一个可以返回任何数字(负数、零或正数)的函数。
但是,基于某些异常,我希望函数返回 Boolean
FALSE
有没有办法编写一个可以返回 int
的函数> 或一个布尔值
?
好的,这已经收到了很多回复。我知道我只是错误地处理了这个问题,我应该在方法中抛出
某种异常。为了获得更好的答案,我将提供一些示例代码。请不要开玩笑:)
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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
不,在 Java 中你不能这样做。
不过,您可以返回一个
Object
。通过返回一个对象,从技术上讲,您可以返回一个派生类,例如 java.lang.Integer 或 java.lang.Boolean。但是,我认为这不是最好的主意。No, you can't do that in Java.
You could return an
Object
though. And by returning an object you could technically return a derived class such asjava.lang.Integer
orjava.lang.Boolean
. However, I don't think it's the best idea.从技术上讲,您可以这样做:
然后这段代码将编译:
但如果该方法返回错误的类型,您很可能会遇到运行时异常。您还必须返回对象而不是基元,因为 T 被擦除为 java.lang.Object,这意味着返回的类型必须扩展 Object(即是一个对象)。上面的示例使用自动装箱来实现原始返回类型。
我当然不会推荐这种方法,因为在我看来,您需要评估异常处理的使用。如果您可以对异常执行某些操作(即恢复、持久、重试等),那么您就可以在异常情况下捕获异常。异常是预期工作流程的一个例外,而不是它的一部分。
You could technically do this:
Then this code would compile:
But you could most certainly encounter runtime exceptions if the method returns the wrong type. You also must return objects instead of primitives because T is erased to java.lang.Object, which means the returned type must extend Object (i.e. be an object). The above example makes use of autoboxing to achieve a primitive return type.
I certainly wouldn't recommend this approach because IMO you need to evaluate your use of exception handling. You catch exceptions in exceptional cases if you can do something with that exception (i.e. recover, persist, retry, etc.). Exceptions are an exception to the expected workflow, not a part of it.
不。您能做的最好的事情就是返回一个处理您可能想要返回的所有内容的类的实例。
显然
,你需要使用这些名称......
而且,这看起来像是代码味道。您可以通过限定您想要在函数之外的路径来消除执行此类操作的需要,然后调用特定函数来获取布尔值或特定函数来获取 int,具体取决于限定。
no. the best you can do is return on instance of a class that handles all the things you might want to return.
something like
obviously, you need to play with the names....
Also, this seems like a code smell. You might be able to remove the need to do something like this by qualifying what path you want outside of your function, and then call a specific function to get a boolean or a specific function to get an int, depending on the qualification.
IEEE 浮点
大多数语言都会处理您的特定示例,而不会出现异常或联合类型,因为 IEEE 浮点包含 NaN 的表示形式。在 Java 中,使用 Double.NaN:
这会产生您想要的确切输出:
异常
异常是解决类似问题的旧 Java 方法:
这是异常的客户端代码。
联合类型
要真正向方法传递不相关的类型或从方法返回不相关的类型,您需要 Java 并不真正支持的联合类型。但 Paguro 提供了 Union 类型 您可以像这样在 Java 中使用它(使用 Or):
结论
对于您的具体示例,只需使用浮点。对于更通用的解决方案,我发现联合类型比异常更有用。您可以使用联合类型作为方法的参数,该方法可能采用两个没有公共接口或祖先的不同输入。它们对函数式编程也更友好。
IEEE Floating Point
Most languages will handle your specific example without Exceptions or union types because IEEE floating point includes a representation for NaN. In Java, use Double.NaN:
That produces your exact output that you wanted:
Exceptions
Exceptions are The Old Java Way of solving similar problems:
Here's your client code for an Exception.
Union Types
To truly pass or return unrelated types to or from a method, you want Union types which Java does not really support. But Paguro provides Union Types which you can use in Java like this (using Or):
Conclusion
For your specific example, just use Floating Point. For a more general solution, I find union types more useful than Exceptions. You can use union types as arguments to a method that might take two different inputs which have no common interface or ancestor. They are also more friendly to Functional Programming.
编写一个返回
对象
的函数。让它返回Boolean
或Integer
包装对象。然后使用instanceof来确定要使用哪个。Write a function that returns an
Object
. Have it either return theBoolean
orInteger
wrapper objects. Then use instanceof to figure out which to use.不,是向客户返回一份参考信息。
您可以编写一个将 boolean 和 int 封装在一起的响应对象,并根据您的想法设置值。
但如果我是用户,我会认为你的设计很混乱。
No, one return reference to a customer.
You can write a response object that encapsulates a boolean and an int together and set the values according to your whim.
But if I was a user I'd think your design was confusing.
我的老师有一个很酷的想法,在 java 中使用类似于 C# 的 tryParse 方法希望它有帮助
my teacher had a cool idea for a tryParse C# like method in java hope it helps
这可能不是最好的解决方案,具体取决于您想要做什么,但解决问题的一个简单方法可能是让函数返回一个 int 或一个超出可能范围的常量(例如 RETURNED_FALSE/TRUE)并检查它。
This may not be the best solution depending on what you want to do, but an easy way to solve the problem might be to have the function return an int or a constant outside the possible range (such as RETURNED_FALSE/TRUE) and check for that.
我想说这是可能的。但不是直接的。
我还没有完成问题中给出的程序。我知道这是一篇旧帖子,所以才回答这个问题。可能会帮助某人。
将您的值添加到如下所示的地图中。并用钥匙获取它!
注意:
这不是一个好的做法。但有时在需要的时候它会有所帮助!
I would say it is possible. But not directly.
I haven't gone through the program given in the question. I am answering this knowing this is an old post. Might help someone.
Add your values to a Map like below. And get it with its key!
Note:
This is not a good practice. But it helps sometimes when it is needed!
绝对地!在您的情况下,由于返回值可以是正数、0、负数或假,因此最好的返回值可能是 JSONObject。在代码中,您可以添加此 import:
并在函数中:
您还可以向 retval 添加另一个键:值对以包含结果类型,以帮助在调用函数中检查它。
Absolutely! In your case, since the return values can be positive, 0, negative, or false, probably the best return value would be a JSONObject. In your code, you would add this import:
and in the function:
You potentially could also add another key:value pair to the retval to include the result type to help with checking it in the calling function.
今天早上早些时候我也想知道同样的事情,我做了一个很好的小解决方法,在我的情况下运行良好。
我想构建一个扩展 AWT
JPanel
的表类,以便我可以将其作为组件添加到JFrame
中。它需要接受一个ArrayList>
来存储所有表数据(本质上是行列表)。但是,该值有时是String
,有时是double
,有时是int
。因此,我创建了一个名为Value
的类,它有 3 个构造函数、一个私有枚举Type
和一个名为getContents()
的返回方法。我的课程是这样安排的:要使用它,我在我的
GopherTable
中使用了它(请忽略名称,它与软件的上下文相关)这个解决方案在我的情况下完美运行,并且AFAIK不会冒犯很多人。有时,您所询问的解决方案并不是您正在寻求的解决方案。有关详细信息,请参阅此链接。
I wondered this same thing earlier this morning, and I made a nice little workaround that functioned well in my circumstance.
I wanted to build a table class that extended the AWT
JPanel
, so that I could add it as a component to aJFrame
. It would need to take in anArrayList<ArrayList<some value>>
that would store all of the tabledata (essentially a list of rows). The value, however, would sometimes be aString
, sometimes adouble
, and sometimes anint
. So I created a class calledValue
which has 3 constructors, a private enumType
, and a return method calledgetContents()
. My class is arranged like so:To use this, I've used it in my
GopherTable
(ignore the name please, it is relevant in the context of the software)This solution worked perfectly in my case and AFAIK wouldn't offend very many people. Sometimes, the solution you are asking about is not the solution you are seeking. See this link for more on that.
inout 参数仅适用于可以变异的对象。对于 String inout 参数,传入 StringBuilders 而不是 Strings,然后replace()它们的值。
inout parameters only work for objects that can be mutated. For String inout parameters, pass in StringBuilders instead of Strings, then replace() their values.