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

Neu*_*ino 43 java pass-by-reference primitive-types

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

Mik*_*ark 74

没有办法通过Java中的引用直接传递原语.

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

public class IntRef { public int value; }
Run Code Online (Sandbox Code Playgroud)

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

Apache commons-lang Mutable*类:
优点:单线程使用的良好性能.完整性.
缺点:引入第三方库依赖项.没有内置的并发控件.
代表类:MutableBoolean,MutableByte,MutableDouble,MutableFloat,MutableInt,MutableLong,MutableObject,MutableShort.

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

长度1原始数组
OscarRyz的答案演示了使用长度为1的数组来"包装"原始值.
优点:快速编写.高性能.不需要第三方图书馆.
缺点:有点脏.没有内置的并发控件.代码中没有(明确地)自我文档的结果:是方法签名中的数组,所以我可以传递多个值?或者它是否作为脚手架传递引用仿真?

另请参阅
StackOverflow问题的答案" Java中的可变布尔字段 ".

我的意见
在Java中,您应该尽量少用或不用上述方法.在C中,通常使用函数的返回值来中继状态代码(SUCCESS/FAILURE),而函数的实际输出通过一个或多个输出参数进行中继.在Java中,最好使用Exceptions而不是返回代码.这释放了用于携带实际方法输出的方法返回值 - 大多数Java程序员发现的设计模式比out参数更自然.


Mar*_*ten 13

java中没有任何内容通过引用传递.这一切都是通过价值传递的.

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

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"
}
Run Code Online (Sandbox Code Playgroud)

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

持有人:

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.
}
Run Code Online (Sandbox Code Playgroud)

具有返回值

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

public int doSomething(int b) {
  return b + 1;
}
Run Code Online (Sandbox Code Playgroud)

  • @tchrist:你可以在没有真正回答问题的情况下做出正确的陈述.我可以说"1 + 1 = 2",这是正确的,但没有回答这个问题.这里的原始答案更接近于回答这个问题,但仍未提供任何对提问者有用的答案. (7认同)
  • 技术上正确,但不是非常有用 (6认同)

Col*_*inD 13

传递一个AtomicInteger,AtomicBoolean等来代替.每种原始类型都没有,但是AtomicReference<Short>如果必要的话,你也可以使用.

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


Osc*_*Ryz 10

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

void demo() { 
    int [] a = { 0 };
    increment ( a ) 
}
void increment( int [] v ) { 
     v[0]++;
}
Run Code Online (Sandbox Code Playgroud)

但总有更好的选择.