我可以在Java中通过引用传递参数吗?
我想要类似于C#
的ref
关键字的语义。
Java令人困惑,因为所有东西都是有价值的 。 然而对于引用types的参数(即不是基本types的参数),它是引用本身 ,它是通过值传递的,因此它看起来是通过引用(人们经常声称它是)。 情况并非如此,如下所示:
Object o = "Hello"; mutate(o) System.out.println(o); private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
将打印Hello
控制台。 如果你希望上面的代码打印Goodbye
的选项是使用明确的参考 ,如下所示:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello"); mutate(ref); System.out.println(ref.get()); //Goodbye! private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
我可以在Java中通过引用传递参数吗?
没有。
为什么? Java 只有一种方法将parameter passing给方法:按值。
注意:
对于基元,这很容易理解:你得到一个值的副本。
对于所有其他你得到一个引用的副本,这也被称为值传递。
这一切都在这张照片里:
在Java中,在语言层面上没有类似于ref的东西 。 在Java中,只有通过价值语义传递
为了好奇,你可以在Java中实现一个类似ref的语义,把你的对象包装在一个可变的类中:
public class Ref<T> { private T value; public Ref(T value) { this.value = value; } public T get() { return value; } public void set(T anotherValue) { value = anotherValue; } @Override public String toString() { return value.toString(); } @Override public boolean equals(Object obj) { return value.equals(obj); } @Override public int hashCode() { return value.hashCode(); } }
testing用例:
public void changeRef(Ref<String> ref) { ref.set("bbb"); } // ... Ref<String> ref = new Ref<String>("aaa"); changeRef(ref); System.out.println(ref); // prints "bbb"
来自James Gosling的“Java编程语言”:
“… Java中只有一个parameter passing模式 – 按值传递 – 这使得事情变得简单…”
我不认为你可以。 你最好的select可能是封装你想通过“ref”到另一个类实例的东西,并传递(外部)类的引用(通过值)。 如果你明白我的意思
即你的方法改变它传递的对象的内部状态,这对调用者是可见的。
Java总是传递价值。
当你传递一个基元时,它是一个值的副本,当你传递一个对象的时候,它就是引用指针的一个副本。
另一个select是使用一个数组,例如void method(SomeClass[] v) { v[0] = ...; }
void method(SomeClass[] v) { v[0] = ...; }
但是1)数组必须在方法调用之前被初始化,2)仍然不能用这种方式实现例如swap方法…这种方式在JDK中使用,例如在java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])
。