如何通过引用传递原始数据类型?
如何在java中通过引用传递原始类型?例如,如何使传递给方法的 int
可以修改?
How can I pass a primitive type by reference in java? For instance, how do I make an int
passed to a method modifiable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
一种选择是使用 java.lang.Integer 之类的类,这样您就根本不会传递原语。
另一方面,您可以使用如下代码:
并让 func 返回修改后的值。
One option is to use classes like java.lang.Integer, then you're not passing a primitive at all.
On the other hand, you can just use code like:
and have func return the modified value.
这在 Java 中是不可能的
That's not possible in Java
传递具有该值的对象作为字段。
Pass an object that has that value as a field.
你不能。但是您可以返回一个整数,它是一个修改值
如果您传递多个值,您可能希望创建一个 数据传输对象(专门包含一组可以传递给类的变量的类)。
You can't. But you can return an integer which is a modified value
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).
这在 Java 中是不可能的,作为替代方案,您可以将其包装在单个元素数组中。
但总有更好的选择。
That's not possible in Java, as an alternative you can wrap it in a single element array.
But there are always better options.
而是传递
AtomicInteger
、AtomicBoolean
等。并不是每种基本类型都有一个,但如果需要的话,您也可以使用AtomicReference
。请注意:在 Java 中很少需要做这样的事情。当您想要执行此操作时,我建议您重新考虑您要尝试执行的操作,并看看是否无法通过其他方式执行此操作(例如,使用返回
int
的方法......到底什么是最好的做法因情况而异)。Pass an
AtomicInteger
,AtomicBoolean
, etc. instead. There isn't one for every primitive type, but you can use, say, anAtomicReference<Short>
if necessary too.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 中没有任何内容是通过引用传递的。都是按值传递的。
编辑:基元和对象类型都是按值传递的。您永远不能更改传递的值/引用并期望原始值/引用发生变化。示例:
绕过这个障碍的唯一方法,无论它是基元还是引用,都是传递容器对象,或使用返回值。
有持有者:
有返回值
Nothing in java is passed by reference. It's all passed by value.
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:
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:
With return value
在 Java 中没有办法直接通过引用传递原语。
解决方法是传递对包装类实例的引用,然后该包装类包含基元作为成员字段。这样的包装类可以非常简单地为您自己编写:
但是一些预构建的包装类怎么样,这样我们就不必编写自己的包装类了? OK:
Apache commons-lang 可变*类:
优点:单线程使用时性能良好。完整性。
缺点:引入第三方库依赖项。没有内置的并发控制。
代表性类:MutableBoolean,MutableByte< /a>, MutableDouble , MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort。
java.util .concurrent.atomic 原子*类:
优点:标准 Java (1.5+) API 的一部分。内置并发控制。
缺点:在单线程设置中使用时,性能影响较小。缺少对某些数据类型的直接支持,例如没有 AtomicShort。
代表性类:AtomicBoolean,AtomicInteger< /a>, AtomicLong和AtomicReference。
注意:作为用户 ColinD 在他的回答中显示,AtomicReference 可以用来近似一些缺失的类,例如 AtomicShort。
长度为1的原始数组
OscarRyz 的回答演示了使用用于“包装”原始值的长度为 1 的数组。
优点:编写速度快。表现出色。不需要第三方库。
缺点:有点脏。没有内置的并发控制。导致代码不(明显)自我记录:方法签名中的数组是否存在,以便我可以传递多个值?或者它在这里作为按引用传递模拟的脚手架?
另请参阅
StackOverflow 问题“Java 中的可变布尔字段”的答案。
我的意见
在 Java 中,您应该尽量少用或根本不使用上述方法。在 C 语言中,通常使用函数的返回值来中继状态代码(成功/失败),而函数的实际输出则通过一个或多个输出参数来中继。在Java中,最好使用异常而不是返回码。这释放了方法返回值,用于携带实际的方法输出——大多数 Java 程序员发现这种设计模式比输出参数更自然。
There isn't a way to pass a primitive directly by reference in 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:
But how about some pre-built wrapper classes, so we don't have to write our own? OK:
The Apache commons-lang Mutable* 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.
The java.util.concurrent.atomic Atomic* 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.
Length 1 primitive array
OscarRyz's answer demonstrates 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?
Also see
The answers to StackOverflow question "Mutable boolean field in 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.