我需要在从方法返回内容列表时返回/更新布尔值。 Java 无法返回元组,而且我不想为此创建一个单独的类,因此我想将 bool 作为输出参数传递。这就是我们的 C++ 客户端所做的,通过引用传递 bool。这适用于普通类,因为 java 具有对象的 pass-by-ref (参见 Is Java“按引用传递”或“按值传递”?对此进行了很好的讨论)。但是像 Boolean 这样的“包装”类将它们的原始值存储为不可变的,因此它不能以这种方式更新。
使用布尔数组(只有一个条目)似乎有些做作,但可能是最简单的方法。或者,可以返回布尔值并将创建的列表作为输出参数而不是返回值传递回来[但是Java客户端偏离了C++,最好保持基本相同的方法——仅供参考,在C#中也需要这个。 ]
I need to return/update a boolean while returning a list of stuff from a method. Java can't return tuples and I didn’t want to make a separate class for this, so figured I would pass the bool as an out param. That’s what our C++ client does, passes bool by reference. That would work for a normal class since java sort of has pass-by-ref for objects (see Is Java "pass-by-reference" or "pass-by-value"? for a good discussion of this). But the “Wrapper” classes like Boolean store their primitive value as immutable, so it can't be updated in this way.
Using a boolean array (with one entry) seems hokey but is perhaps the simplest thing that works. Alternatively, could return the boolean and pass the created list back as an out param rather than as the return [but then the java client deviates from the C++, and it's best if they keep mostly the same approach- FYI need this in C# too.]
发布评论
评论(6)
不,Java没有对象的引用传递;它有“按值传递引用”,这不是一回事。
您绝对不能在 Java 中将任何内容作为“out”参数或通过引用传递 - 尽管在 C# 中可以。
你能将“布尔加列表”封装成另一种类型吗?他们真的有关系吗?使用布尔数组绝对是相当难看的。您可以编写一个
MutableBoolean
包装类型 - 但同样,这非常丑陋。通常我会说返回两个东西表明该方法应该被拆分,但是当其中一个是布尔值时,它可能相当合理 - 就像 C# 中的int.TryParse
等。No, Java doesn't have pass-by-ref for objects; it has "pass reference by value" which isn't the same thing.
You definitely can't pass anything as an "out" parameter or by reference in Java - although you could in C#.
Could you encapsulate the "Boolean plus list" into another type? Are they actually related? Using a boolean array is definitely pretty ugly. You could write a
MutableBoolean
wrapper type - but again, that's pretty ugly. Normally I'd say that returning two things suggests the method should be split up, but when one of them is a Boolean it can be fairly reasonable - likeint.TryParse
etc from C#.正如您所说,布尔包装类是不可变的,因此您不能使用它来接收输出变量。
传递一个新列表来接收列表结果并返回布尔值对我来说听起来最自然,但你有一个很好的理由;在多个实现中保持接口大致相同。
您可以通过创建自己的可变布尔值并传递对其的引用来解决此问题,例如:
并使用它,例如:
As you say, The Boolen wrapper class is immutable, so you cannot use it to receive your output variable.
Passing in a new list to receive the list result and returning the boolean would sound most natural to me, but you have a good reason; keeping the interface roughly the same over multiple implementations.
You could solve this problem by creating your own mutable Boolean and passing a reference to it, something like:
and use it like:
我遇到了同样的问题,恕我直言,最好的解决方案通常是:
忘记你的担忧,并创建一个单独的类。< /strong>
我曾经对此犹豫不决,但类是用来封装值的,所以就去做吧。
有可能,一旦您的函数返回自定义类的实例,您就会发现有一些非常适合该类的附加功能,或者可以使用该类作为参数或返回值的其他方法,并且很快该类将被相当有用:-)。
如果您真的不想这样做,您可以随时将所有内容填充到 java.util.List 或 java.util.Map 中并返回。但这真的很丑陋:-(我也这样做了,然后后悔了。一开始看起来可能很简单,但随着代码的发展和增长,可读性会受到影响(是一个整数列表,然后是双精度列表,还是反之亦然?)。
注意:如果您觉得顶级常规类太过分了,您可以使用 嵌套类,这对于仅“本地使用”的类来说很好。
I've encountered the same problem, and the best solution IMHO is usually:
Just forget your worries, and make a separate class.
I used to be hesitant about this, but classes are meant for encapsulating values, so go ahead and do it.
Chances are, once your function returns an instance of a custom class, you will find that there is additional functionality that fits well into that class, or other methods that could use the class as a parameter or return value, and soon the class will be fairly useful :-).
If you really don't want to do this, you can always stuff everything into a java.util.List or a java.util.Map and return that. But that's really ugly :-( I've done that as well, and come to regret it. It may seem simple at first, but as the code evolves and grows, readability suffers (was that a List of Integer, then Double, or vice versa?). Classes are much more helpful.
Note: If you feel a top-level regular class is overkill, you can use a nested class, which is nice for classes for "local use" only.
您不能使用任何基本类型作为 Java 中的“out”参数。这种事永远不会发生。
您也不能使用任何对象版本(例如 Boolean、Integer、Float、Double 等)作为“输出”参数,因为它们是不可变的。您可以做的就是编写自己的类或在 commons-lang 中使用类似 MutableBoolean 的内容(http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/mutable/MutableBoolean .html)。
例如:
You cannot use any of the primitive types as an 'out' parameter in Java. That's just not going to happen any time.
You also can't use any of the object versions, such as Boolean, Integer, Float, Double, etc, as 'out' parameters as they are immutable. What you can do is either write your own class or use something like MutableBoolean in commons-lang (http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/mutable/MutableBoolean.html).
For example:
我为返回多个值所做的是将返回类型更改为返回对象数组。 [0] 可以是布尔值,[1] 可以是列表。
缺点是调用者必须知道如何从对象数组中适当地转换返回的对象,并且编译器无法为您进行检查。
编辑:这里是一个SO从 Java 返回一对值的答案。
What I've done to return multiple values is to change the return type to return an object array. The [0] could be the bool and [1] could be the list.
The downside is that the caller must know to cast the returned objects appropriately from the object array, and the compiler can't check for you.
Edit: Here is a SO answer for returning a pair of values from Java.
正如 rsp 和许多其他人提到的,它是不可变的。但是,有一个布尔变体,称为 AtomicBoolean 作为 java.util.concurrent.atomic 包。如果您不想创建类来处理此类琐碎问题,AtomicBoolean 是最佳选择。一探究竟。运行以下代码亲自查看。
As rsp and many others have mentioned, it is immutable. However, there is a boolean variation called AtomicBoolean that was introduced as part of the java.util.concurrent.atomic package in Java version 1.5. If you do not want to create classes for handling such trivial issues, AtomicBoolean is the way to go. Check it out. Run the following code to see for yourself.