2010-11-30 51 views

回答

67

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

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

public class IntRef { public int value; } 

但如何对一些预先建立的包装类,所以我们没有写我们自己?OK:

阿帕奇commons-lang易变*类:
优势:单线程应用性能良好。完整性。
缺点:引入了第三方库依赖项。没有内置的并发控制。
代表类MutableBooleanMutableByteMutableDoubleMutableFloatMutableIntMutableLongMutableObjectMutableShort

java.util.concurrent.atomic原子*类:
优势:标准的Java(1.5+)API的一部分。内置并发控制。
缺点:在单线程设置中使用时性能较低。缺少对某些数据类型的直接支持,例如没有AtomicShort。
代表类AtomicBooleanAtomicIntegerAtomicLongAtomicReference
注意:作为用户ColinD shows in his answer,可以使用AtomicReference来近似一些缺失的类,例如, AtomicShort。

长度1个基本数组
OscarRyz's answer展示了使用一个长度为1数组“包装”一个原始值。
优点:快写。高性能。没有必要的第三方图书馆。
缺点:有点脏。没有内置的并发控制。结果在代码中没有(明显)自我文档:是方法签名中的数组,所以我可以传递多个值?还是在这里作为传递参考模拟的脚手架?

另见
来的StackOverflow问题 “Mutable boolean field in Java” 的答案。

我的意见的
在Java中,你要努力少量或完全不使用上述方法。在C中,通常使用函数的返回值来中继状态码(SUCCESS/FAILURE),而函数的实际输出则通过一个或多个输出参数中继。在Java中,最好使用异常而不是返回码。这释放了方法返回值以用于实现实际的方法输出 - 一种大多数Java程序员发现比超参数更自然的设计模式。

1

这在Java中不可行

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" 
} 

的唯一方法来解决这一关,无论它是一个原始或参考的,是通过一个容器对象,或使用返回值。

有支架:

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

随着返回值

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

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

技术上正确,但不是非常有帮助 – 2010-11-30 23:34:29

+0

好吧,我会澄清。 – 2010-11-30 23:35:14

+0

“正确”是一个布尔条件,并且不允许度数或类型的修饰符。 – tchrist 2010-12-01 05:01:18

2

传递具有该值作为一个场中的物体。

-2

一种选择是使用像java.lang.Integer这样的类,那么你根本不会传递一个原语。

在另一方面,你可以使用如下代码:

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

,并FUNC返回修改后的值。

3

你不行。但是你可以返回一个整数,它是一个修正值

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

如果要传递一个以上的你不妨(特别是一类含有一组变量可以传递到类)创建Data Transfer Object

13

改为通过AtomicIntegerAtomicBoolean等。对于每种原始类型都没有,但如果需要的话,也可以使用AtomicReference<Short>

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

10

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

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

但总有更好的选择。