我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
查看此代码. 此代码不会扔 NullPointerException... 它将打印“Vinay”
public class Main {
public static void main(String[] args) {
String temp = "Vinay";
print(temp);
System.err.println(temp);
}
private static void print(String temp) {
temp = null;
}
}
如果 Java 通过参考,则应该将 NullPointerException 扔下来,因为参考设置为 Null。
其他回答
Java 使用 pass-by-value,但效果不同的是你是否使用原始或参考类型。
当你将原始类型作为论点转移到一种方法时,它将获得原始类型的副本,而方法块内的任何变化都不会改变原始变量。
当您将参考类型作为一个论点转移到一个方法时,它仍然得到一个副本,但它是对对象的参考的副本(换句话说,您正在获得记忆地址的副本在对象所在地),因此对象中的任何变化在方法的区块内将影响原始对象在区块外。
我从一本关于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
我只是注意到你提到我的文章。
了解这一点的关键是,这样的事情
Dog myDog;
它不是狗;它实际上是指向狗。在Java中使用“参考”这个术语是非常误导性的,这引起了大多数混乱。
这意味着,当你有
Dog myDog = new Dog("Rover");
foo(myDog);
您基本上将创建的狗对象的地址转移到 foo 方法。
public void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
让我们看看发生了什么。
这里是钥匙。
记住 myDog 是指标,而不是真正的狗,答案是 NO. myDog 仍然有值 42;它仍然指向原始狗(但请注意,由于“AAA”线,它的名字现在是“Max” - 仍然是相同的狗; myDog 的值没有改变)。
在 C++、Ada、Pascal 和支持 pass-by-reference 的其他语言中,您实际上可以更改已通过的变量。
void swap(int *x, int *y) {
int t = *x;
*x = *y;
*y = t;
}
int x = 1;
int y = 2;
swap(&x, &y);
该功能将指标传递给数据,并跟随这些指标访问和修改这些数据。
void swap(int[] x, int[] y) {
int temp = x[0];
x[0] = y[0];
y[0] = temp;
}
int[] x = {1};
int[] y = {2};
swap(x, y);
我觉得关于“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);
}
此分類上一篇
所以,值,参考?你说“土豆”。
理解它在两个步骤:
您无法更改对象本身的参考,但您可以使用此已过的参数作为对象的参考。
如果您想要更改参考背后的值,您只会在同一名称“d”的字符串上宣布一个新的变量。
public static void foo(Dog d) {
d.Name = "belly";
System.out.println(d); //Reference: Dog@1540e19d
d = new Dog("wuffwuff");
System.out.println(d); //Dog@677327b6
}
public static void main(String[] args) throws Exception{
Dog lisa = new Dog("Lisa");
foo(lisa);
System.out.println(lisa.Name); //belly
}