[英]How do I pass a primitive data type by reference?
How can I pass a primitive type by reference in java? 如何在java中通过引用传递原始类型? For instance, how do I make an int
passed to a method modifiable? 例如,如何将int
传递给可修改的方法?
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-lang Mutable* classes: Apache commons-lang Mutable *类:
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 . 代表类 : MutableBoolean , MutableByte , MutableDouble , MutableFloat , MutableInt , MutableLong , MutableObject , MutableShort 。
The java.util.concurrent.atomic Atomic* classes: java.util.concurrent.atomic Atomic *类:
Advantages : Part of the standard Java (1.5+) API. 优点 :标准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, eg there is no AtomicShort. 缺少对某些数据类型的直接支持,例如没有AtomicShort。
Representative classes : AtomicBoolean , AtomicInteger , AtomicLong , and AtomicReference . 代表类 : AtomicBoolean , AtomicInteger , AtomicLong和AtomicReference 。
Note : As user ColinD shows in his answer , AtomicReference can be used to approximate some of the missing classes, eg AtomicShort. 注意 :正如用户ColinD 在他的回答中所示 ,AtomicReference可用于估计一些缺失的类,例如AtomicShort。
Length 1 primitive array 长度为1的原始数组
OscarRyz's answer demonstrates using a length 1 array to "wrap" a primitive value. OscarRyz的答案演示了使用长度为1的数组来“包装”原始值。
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 ". StackOverflow的答案问题“ Java中的可变布尔字段 ”。
My Opinion 我的看法
In Java, you should strive to use the above approaches sparingly or not at all. 在Java中,您应该尽量少用或不用上述方法。 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. 在C中,通常使用函数的返回值来中继状态代码(SUCCESS / FAILURE),而函数的实际输出通过一个或多个输出参数进行中继。 In Java, it is best to use Exceptions instead of return codes. 在Java中,最好使用Exceptions而不是返回代码。 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程序员发现的设计模式比out参数更自然。
Nothing in java is passed by reference. java中没有任何内容通过引用传递。 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: 例:
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;
}
Pass an AtomicInteger
, AtomicBoolean
, etc. instead. AtomicBoolean
,传递一个AtomicInteger
, AtomicBoolean
等。 There isn't one for every primitive type, but you can use, say, an AtomicReference<Short>
if necessary too. 每种原始类型都没有,但如果需要,您可以使用AtomicReference<Short>
。
Do note: there should very rarely be a need to do something like this in Java. 请注意:在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). 当你想要这样做的时候,我建议你重新考虑你想要做的事情,看看你是不是可以用其他方式去做(使用返回int
的方法,比如说...究竟最好的是什么做的将因情况而异)。
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. 但总有更好的选择。
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). 如果您传递的不止一个,您可能希望创建一个数据传输对象 (一个专门用于包含一组可以传递给类的变量的类)。
将具有该值的对象作为字段传递。
这在Java中是不可能的
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返回修改后的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.