在 Java 中将原始类型作为 out 参数传递

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2224342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 20:08:50  来源:igfitidea点击:

Passing primitive types as out param in Java

javaparameterspass-by-reference

提问by Cincinnati Joe

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.

我需要在从方法返回内容列表时返回/更新布尔值。Java 不能返回元组,我不想为此创建一个单独的类,所以我想我会将 bool 作为输出参数传递。这就是我们的 C++ 客户端所做的,通过引用传递 bool。这适用于普通类,因为 java 有点为对象传递引用(请参阅Java 是“传递引用”还是“传递值”?对此进行了很好的讨论)。但是像 Boolean 这样的“Wrapper”类将它们的原始值存储为不可变的,因此不能以这种方式更新。

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.]

使用布尔数组(带有一个条目)似乎很笨拙,但可能是最简单的方法。或者,可以返回布尔值并将创建的列表作为输出参数传回,而不是作为返回值 [但是 Java 客户端与 C++ 不同,最好他们保持大致相同的方法 - 仅供参考,我在 C# 中也需要这个。 ]

回答by Jon Skeet

No, Java doesn'thave pass-by-ref for objects; it has "pass reference by value" which isn't the same thing.

不,Java没有对象的传递引用;它具有“按值传递引用”,这不是一回事。

You definitely can't pass anything as an "out" parameter or by reference in Java - although you could in C#.

您绝对不能在 Java 中将任何内容作为“输出”参数或通过引用传递——尽管您可以在 C# 中。

Could you encapsulate the "Boolean plus list" into another type? Are they actually related? Using a boolean array is definitely pretty ugly. You couldwrite a MutableBooleanwrapper 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 - like int.TryParseetc from C#.

你能把“布尔加列表”封装成另一种类型吗?他们真的有关系吗?使用布尔数组绝对是非常丑陋的。你可以写一个MutableBoolean包装类型 - 但同样,这很丑陋。通常我会说返回两个东西表明应该拆分该方法,但是当其中一个是布尔值时,它可能是相当合理的 - 就像int.TryParseC# 中的等。

回答by rsp

As you say, The Boolen wrapper class is immutable, so you cannot use it to receive your output variable.

正如您所说,Boolen 包装类是不可变的,因此您不能使用它来接收您的输出变量。

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:

您可以通过创建自己的可变布尔值并传递对它的引用来解决此问题,例如:

public class Example {
    public class BooleanResult {
        private boolean result;

        public void setResult(boolean value) { result = value; }
        public boolean getResult() { return result; }
    }

    // ....
    public List doSomething(BooleanResult out) {
        List list;
        boolean result;

        // ...

        out.setResult(result);

        return list;
    }
}

and use it like:

并像这样使用它:

Example.BooleanResult out = new Example.BooleanResult();

List list = example.doSomething(out);

boolean result = out.getResult();

回答by sleske

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

我需要在从方法返回内容列表时返回/更新布尔值。Java 不能返回元组,我不想为此创建一个单独的类

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 reallydon'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.

如果你真的不想这样做,你总是可以把所有东西都塞进 java.util.List 或 java.util.Map 并返回它。但这真的很难看:-( 我也这样做了,然后后悔了。起初看起来很简单,但随着代码的发展和增长,可读性受到影响(是整数列表,然后是双精度数,还是反之亦然?)课程更有帮助。

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.

注意:如果您觉得顶级常规类有点过分,您可以使用嵌套类,这对于仅用于“本地使用”的类非常有用。

回答by Barney Govan

You cannot use any of the primitive types as an 'out' parameter in Java. That's just not going to happen any time.

在 Java 中,您不能将任何原始类型用作“输出”参数。这在任何时候都不会发生。

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).

您也不能使用任何对象版本,例如 Boolean、Integer、Float、Double 等,作为“输出”参数,因为它们是不可变的。您可以做的是编写自己的类或在 commons-lang ( http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/可变/MutableBoolean.html)。

For example:

例如:

public void setTrue(MutableBoolean b) {
    b.setValue(Boolean.TRUE);
}

回答by aaaa bbbb

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.

我所做的返回多个值是更改返回类型以返回一个对象数组。[0] 可能是布尔值,[1] 可能是列表。

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: Hereis a SO answer for returning a pair of values from Java.

编辑:是从 Java 返回一对值的 SO 答案。

回答by Srikanth

As rsp and many others have mentioned, it is immutable. However, there is a boolean variation called AtomicBooleanthat was introduced as part of the java.util.concurrent.atomicpackage 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.

正如 rsp 和许多其他人所提到的,它是不可变的。但是,在 Java 1.5 版中,作为java.util.concurrent.atomic包的一部分引入了一个名为AtomicBoolean的布尔变量。如果您不想创建类来处理这些琐碎的问题,那么 AtomicBoolean 是您的最佳选择。看看这个。运行以下代码亲自查看。

public static void main(String[] args) {
    AtomicBoolean value = new AtomicBoolean(false);
    System.out.println(value); // Prints false
    someMethod(value);
    System.out.println(value); // Prints true
}

void someMethod(AtomicBoolean a) {
    a.set(true);
}