Java 如何通过引用传递原始数据类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4319537/
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-08-14 15:49:36  来源:igfitidea点击:

How do I pass a primitive data type by reference?

javapass-by-referenceprimitive-types

提问by Neuquino

How can I pass a primitive type by reference in java? For instance, how do I make an intpassed to a method modifiable?

如何在java中通过引用传递原始类型?例如,如何使int传递给方法的可修改?

采纳答案by Mike Clark

There isn't a way to pass a primitive directly by reference in Java.

在 Java 中没有直接通过引用传递原语的方法。

A workaround is to instead pass a reference to an instance of a wrapper class, which then contains the primitive as a member field. Such a wrapper class could be extremely simple to write for yourself:

一种解决方法是将引用传递给包装类的实例,然后该类包含原语作为成员字段。为自己编写这样的包装类可能非常简单:

public class IntRef { public int value; }

But how about some pre-built wrapper classes, so we don't have to write our own? OK:

但是一些预先构建的包装类怎么样,这样我们就不必编写自己的了?好的:

The Apache commons-langMutable* classes:
Advantages: Good performance for single threaded use. Completeness.
Disadvantages: Introduces a third-party library dependency. No built-in concurrency controls.
Representative classes: MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.

Apache commons-langMutable* 类:
优点:单线程使用的良好性能。完整性。
缺点:引入了第三方库依赖。没有内置的并发控制。
代表类MutableBooleanMutableByteMutableDoubleMutableFloatMutableIntMutableLongMutableObjectMutableShort

The java.util.concurrent.atomicAtomic* classes:
Advantages: Part of the standard Java (1.5+) API. Built-in concurrency controls.
Disadvantages: Small performance hit when used in a single-threaded setting. Missing direct support for some datatypes, e.g. there is no AtomicShort.
Representative classes: AtomicBoolean, AtomicInteger, AtomicLong, and AtomicReference.
Note: As user ColinD shows in his answer, AtomicReference can be used to approximate some of the missing classes, e.g. AtomicShort.

java.util.concurrent.atomic中的原子*类:
优点:标准的Java(1.5+)API的一部分。内置并发控制。
缺点:在单线程设置中使用时性能损失小。缺少对某些数据类型的直接支持,例如没有 AtomicShort。
代表类AtomicBooleanAtomicIntegerAtomicLongAtomicReference
注意:正如用户 ColinD在他的回答中所示,AtomicReference 可用于近似某些缺失的类,例如 AtomicShort。

Length 1 primitive array
OscarRyz's answerdemonstrates using a length 1 array to "wrap" a primitive value.
Advantages: Quick to write. Performant. No 3rd party library necessary.
Disadvantages: A little dirty. No built-in concurrency controls. Results in code that does not (clearly) self-document: is the array in the method signature there so I can pass multiple values? Or is it here as scaffolding for pass-by-reference emulation?

长度为 1 的原始数组
OscarRyz 的回答演示了使用长度为 1 的数组来“包装”原始值。
优点:书写快。表现力。不需要第 3 方库。
缺点:有点脏。没有内置的并发控制。导致没有(显然)自我记录的代码:方法签名中的数组是否存在以便我可以传递多个值?或者它在这里作为传递引用仿真的脚手架?

Also see
The answers to StackOverflow question "Mutable boolean field in Java".

另请参阅
StackOverflow 问题“ Java 中的可变布尔字段”的答案。

My Opinion
In Java, you should strive to use the above approaches sparingly or not at all. In C it is common to use a function's return value to relay a status code (SUCCESS/FAILURE), while a function's actual output is relayed via one or more out-parameters. In Java, it is best to use Exceptions instead of return codes. This frees up method return values to be used for carrying the actual method output -- a design pattern which most Java programmers find to be more natural than out-parameters.

我的意见
在 Java 中,您应该尽量少使用或根本不使用上述方法。在 C 中,通常使用函数的返回值来传递状态代码(成功/失败),而函数的实际输出则通过一个或多个输出参数传递。在 Java 中,最好使用异常而不是返回码。这释放了方法返回值以用于承载实际的方法输出——大多数 Java 程序员发现这种设计模式比输出参数更自然。

回答by a_horse_with_no_name

That's not possible in Java

这在 Java 中是不可能的

回答by Martin Algesten

Nothing in java is passed by reference. It's all passed by value.

java中没有任何东西是通过引用传递的。都是按值传递的。

Edit:Both primitives and object types are passed by value. You can never alter the passed value/reference and expect the originating value/reference to change. Example:

编辑:原语和对象类型都是按值传递的。您永远不能改变传递的值/引用并期望原始值/引用发生变化。例子:

String a;
int b;

doSomething(a, b);

...

public void doSomething(String myA, int myB) {
   // whatever I do to "myA" and "myB" here will never ever ever change
   // the "a" and "b"
}

The only way to get around this hurdle, regardless of it being a primitive or reference, is to pass a container object, or use the return value.

绕过这个障碍的唯一方法,不管它是原始的还是引用,是传递一个容器对象,或者使用返回值。

With a holder:

带支架:

private class MyStringHolder {
  String a;
  MyStringHolder(String a) {
    this.a = a;
  }
}

MyStringHolder holdA = new MyStringHolder("something");

public void doSomething(MyStringHolder holder) {
   // alter holder.a here and it changes.
}

With return value

有返回值

int b = 42;
b = doSomething(b);

public int doSomething(int b) {
  return b + 1;
}

回答by Dan D.

Pass an object that has that value as a field.

将具有该值的对象作为字段传递。

回答by DGH

One option is to use classes like java.lang.Integer, then you're not passing a primitive at all.

一种选择是使用 java.lang.Integer 之类的类,那么您根本不会传递原语。

On the other hand, you can just use code like:

另一方面,您可以使用以下代码:

int a = 5;
a = func(a);

and have func return the modified value.

并让 func 返回修改后的值。

回答by peter.murray.rust

You can't. But you can return an integer which is a modified value

你不能。但是你可以返回一个整数,它是一个修改后的值

int i = 0;
i = doSomething(i);

If you are passing in more than one you may wish to create a Data Transfer Object(a class specifically to contain a set of variables which can be passed to classes).

如果您传入多个,您可能希望创建一个数据传输对象(一个专门包含一组可以传递给类的变量的类)。

回答by ColinD

Pass an AtomicInteger, AtomicBoolean, etc. instead. There isn't one for every primitive type, but you can use, say, an AtomicReference<Short>if necessary too.

传递一个AtomicIntegerAtomicBoolean等来代替。不是每个原始类型都有一个,但你也可以使用,比如说,AtomicReference<Short>如果有必要的话。

Do note: there should very rarely be a need to do something like this in Java. When you want to do it, I'd recommend rethinking what you're trying to do and seeing if you can't do it some other way (using a method that returns an int, say... what exactly the best thing to do is will vary from situation to situation).

请注意:在 Java 中应该很少需要做这样的事情。当你想做的时候,我建议你重新考虑你想要做什么,看看你是否不能以其他方式做(使用一个返回 的方法int,比如说......什么是最好的事情会因情况而异)。

回答by OscarRyz

That's not possible in Java, as an alternative you can wrap it in a single element array.

这在 Java 中是不可能的,作为替代方案,您可以将其包装在单个元素数组中。

void demo() { 
    int [] a = { 0 };
    increment ( a ) 
}
void increment( int [] v ) { 
     v[0]++;
}

But there are always better options.

但总有更好的选择。