我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
Java 总是通过值的参数. Java 中的所有对象参考都通过值. 这意味着将值的副本转移到一个方法. 但技巧是通过值的副本也会改变对象的实际值。
请参见下面的例子,
public class ObjectReferenceExample {
public static void main(String... doYourBest) {
Student student = new Student();
transformIntoHomer(student);
System.out.println(student.name);
}
static void transformIntoDuleepa(Student student) {
student.name = "Duleepa";
}
}
class Student {
String name;
}
在此情况下,它将是Duleepa! 原因是Java对象变量只是指在记忆中真正的对象的参考。 因此,即使Java通过值的参数到方法,如果变量点到对象的参考,实际对象也会被更改。
其他回答
Java 总是使用 Call by Value. 这意味着该方法获得所有参数值的副本。
考虑下列三种情况:
1、试图改变原始变量
public static void increment(int x) { x++; }
int a = 3;
increment(a);
x 将复制一个值,并将增加 x,一个将保持相同的值
(二)试图改变对象的原始领域
public static void increment(Person p) { p.age++; }
Person pers = new Person(20); // age = 20
increment(pers);
p 将复制个体的参考值,并将增加年龄领域,变量是指相同的对象,所以年龄改变。
(三)试图改变参考变量的参考值
public static void swap(Person p1, Person p2) {
Person temp = p1;
p1 = p2;
p2 = temp;
}
Person pers1 = new Person(10);
Person pers2 = new Person(20);
swap(pers1, pers2);
呼叫交换 p1 后,p2 复制 pers1 和 pers2 的参考值与值交换,因此 pers1 和 pers2 仍然相同。
因此,您只能在将参考值复制到该对象时更改对象的字段。
我从一本关于Java认证的书中取了这个代码和解释,并做了一些小变化,我认为这是一个很好的图像,通过对象的价值。在下面的代码中,重新分配g不会重新分配f!在条()方法的结尾,创建了两个Foo对象,一个是由当地变量f和一个是由当地(论点)变量g提到的。
package test.abc;
public class TestObject {
/**
* @param args
*/
public static void main(String[] args) {
bar();
}
static void bar() {
Foo f = new Foo();
System.out.println("Object reference for f: " + f);
f.setName("James");
doStuff(f);
System.out.println(f.getName());
//Can change the state of an object variable in f, but can't change the object reference for f.
//You still have 2 foo objects.
System.out.println("Object reference for f: " + f);
}
static void doStuff(Foo g) {
g.setName("Boo");
g = new Foo();
System.out.println("Object reference for g: " + g);
}
}
package test.abc;
public class Foo {
public String name = "";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
对象参考 f: test.abc.Foo@62f72617
我觉得关于“pass-by-reference vs pass-by-value”的争论并不太有用。
在我们到达Java实施之前,滑板/滑板上走路:价值观以顺序的方式滑板上走路,就像一家咖啡馆里的滑板一样。 滑板中的记忆(也称为动态记忆)是危险的,不组织的。
好吧! 首先,地方原始人走在地板上,所以这个代码:
int x = 3;
float y = 101.1f;
boolean amIAwesome = true;
此分類上一篇
当你宣布和即时一个对象时,实际对象会走在地板上,什么会走在地板上?对象的地址会走在地板上,C++程序员会称之为指标,但一些Java开发人员反对“指标”这个词。
像这样:
int problems = 99;
String name = "Jay-Z";
此分類上一篇
JButton[] marxBros = new JButton[3];
marxBros[0] = new JButton("Groucho");
marxBros[1] = new JButton("Zeppo");
marxBros[2] = new JButton("Harpo");
此分類上一篇
private static void shout(String name){
System.out.println("There goes " + name + "!");
}
public static void main(String[] args){
String hisName = "John J. Jingleheimerschmitz";
String myName = hisName;
shout(myName);
}
此分類上一篇
所以,值,参考?你说“土豆”。
正如许多人之前提到的那样,Java总是有价值的。
下面是另一个例子,这将帮助你理解差异(经典交换例子):
public class Test {
public static void main(String[] args) {
Integer a = new Integer(2);
Integer b = new Integer(3);
System.out.println("Before: a = " + a + ", b = " + b);
swap(a,b);
System.out.println("After: a = " + a + ", b = " + b);
}
public static swap(Integer iA, Integer iB) {
Integer tmp = iA;
iA = iB;
iB = tmp;
}
}
印刷:
前: a = 2, b = 3 后: a = 2, b = 3
这是因为 iA 和 iB 是新的本地参考变量,具有相同值的过去参考(他们的点到 a 和 b 相应)。因此,试图改变 iA 或 iB 的参考将仅在本地范围内变化,而不是在该方法之外。
基本上,重新定义对象参数不会影响论点,例如,
private static void foo(Object bar) {
bar = null;
}
public static void main(String[] args) {
String baz = "Hah!";
foo(baz);
System.out.println(baz);
}
这个工作的原因是因为字符串是 baz 的值的副本,这只是“Hah!”的参考。如果它是实际的参考本身,那么 foo 会重新定义 baz 到 null。