题目:java是引用传递还是值传递?
例子
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Main
{
public static void main( String[] args ){
Dog aDog = new Dog("Max");
foo(aDog);
if (aDog.getName().equals("Max")) { //true
System.out.println( "Java passes by value." );
} else if (aDog.getName().equals("Fifi")) {
System.out.println( "Java passes by reference." );
}
}
public static void foo(Dog d) {
boolean b1= d.getName().equals("Max"); // true
System.out.println("d.getName().equals(Max) "+b1);
d = new Dog("Fifi");
boolean b2 = d.getName().equals("Fifi"); // true
System.out.println("d.getName().equals(Fifi) "+b2);
}
}
class Dog{
private String name;
public Dog(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
}
输出
d.getName().equals(Max) true
d.getName().equals(Fifi) true
Java passes by value.
解释
In this example aDog.getName()
will still return "Max"
. The value aDog
within main
is not overwritten in the function foo
with the Dog “Fifi
” as the object reference is passed by value. If it were passed by reference, then the aDog.getName()
in main would return “Fifi
” after the call to foo
.
这个说的不明不白的
Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。
如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.
如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。
参考来源
这个连接中给的例子
public class Main
{
public static void main(String[] args)
{
Foo f = new Foo("f");
changeReference(f); // It won't change the reference!
modifyReference(f); // It will change the object that the reference variable "f" refers to!
}
public static void changeReference(Foo a)
{
Foo b = new Foo("b");
a = b;
}
public static void modifyReference(Foo c)
{
c.setAttribute("c");
}
}
Foo createFoo()
{
Foo foo = new Foo();
return foo;
}
I will explain this in steps:
1- Declaring a reference named f of type Foo and assign it to a new object of type Foo with an attribute
Foo f = new Foo("f");
2- From the method side, a reference of type Foo with a name a is declared and it’s initially assigned to null.
public static void changeReference(Foo a)
3- As you call the method changeReference, the reference a will be assigned to the object which is passed as an argument.
changeReference(f);
4- Declaring a reference named b of type Foo and assign it to a new object of type Foo with an attribute “b”.
Foo b = new Foo("b");
5- a = b is re-assigning the reference a NOT f to the object whose its attribute is “b”.
6- As you call modifyReference(Foo c) method, a reference c is created and assigned to the object with attribute “f”.
7- c.setAttribute(“c”); will change the attribute of the object that reference c points to it, and it’s same object that reference f points to it.
本专题来源stackoverflow 标签是java的投票数比较高的问题以及回答,我只对上面的回答根据自己的理解做下总结。