是Java“通过
我一直认为Java是通过引用 。 不过,我见过一些博客文章(例如,这个博客),声称它不是。 我不认为我理解他们的区别。
什么是解释?
Java始终是按值传递的 。 不幸的是,他们决定将对象的位置称为“参考”。 当我们传递一个对象的值时,我们将引用传递给它。 这对初学者来说很混乱。
它是这样的:
public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    // we pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true, java passes by value
    aDog.getName().equals("Fifi"); // false 
}
public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // change d inside of foo() to point to a new Dog instance "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}
  在上面的例子中, aDog.getName()仍然会返回"Max" 。  在函数foo , Dog "Fifi"没有改变main的值aDog ,因为对象引用是按值传递的。  如果它通过引用传递,那么在调用foo之后, main的aDog.getName()将返回"Fifi" 。 
同样:
public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
}
public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // this changes the name of d to be "Fifi"
    d.setName("Fifi");
}
  在上面的例子中, Fifi是调用foo(aDog)之后的狗的名字,因为该对象的名字是在foo(...) 。  任何foo在d上执行的操作都是这样的,为了所有实际目的,它们都是在aDog本身上执行的(除非将d更改为指向不同的Dog实例,如d = new Dog("Boxer") )。 
我只是注意到你引用了我的文章。
Java Spec说,Java中的所有东西都是按值传递的。 Java中没有“传递参考”这样的东西。
理解这一点的关键是类似的东西
Dog myDog;
不是狗; 它实际上是一个指向狗的指针。
这意味着什么,当你有
Dog myDog = new Dog("Rover");
foo(myDog);
  你基本上把创建的Dog对象的地址传递给foo方法。 
(我说的本质上是因为Java指针不是直接地址,但最简单的方法就是这样想)
  假设Dog对象驻留在内存地址42上。这意味着我们将42传递给该方法。 
如果方法被定义为
public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC
}
让我们看看发生了什么。
someDog被设置为值42 someDog Dog跟随它指向的Dog (地址42处的Dog对象) Dog (地址42处的Dog )被要求将他的名字改为Max Dog被创建。  假设他在地址74 someDog分配给74 Dog跟随它指向的Dog (地址为74的Dog对象) Dog (地址为74的那个)被要求将他的名字改为Rowlf 现在让我们考虑一下在该方法之外发生的事情:
  myDog是否改变了? 
有关键。
  记住myDog是一个指针,而不是真正的Dog ,答案是NO。  myDog仍然有值42;  它仍然指向原来的Dog (但请注意,因为“AAA”行,它的名字现在是“最大” - 仍然是狗; myDog的值没有改变。) 
遵循地址并改变结尾是完全有效的; 但不会改变变量。
Java的工作方式与C完全一样。您可以指定一个指针,将指针传递给方法,跟随方法中的指针并更改指向的数据。 但是,您无法更改指针指向的位置。
在C ++,Ada,Pascal和其他支持通过引用的语言中,您实际上可以更改传递的变量。
  要是Java传递by-reference语义中, foo我们在上面定义的方法会改变其中myDog指着时分配someDog上线BBB。 
将引用参数看作是传入变量的别名。当分配了别名时,传入的变量也是如此。
Java总是通过值传递参数而不是通过引用。
让我通过一个例子来解释这一点:
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 modify 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");
     }
}
我将逐步解释这一点:
  声明一个名为f的Foo类型的引用,并将其赋值给一个具有属性"f" Foo类型的新对象。 
Foo f = new Foo("f");
  在方法方面,声明了一个名为a Foo类型的引用,并且它的初始null 。 
public static void changeReference(Foo a)
  在调用方法changeReference ,引用a将被分配给作为参数传递的对象。 
changeReference(f);
  声明一个名为b的Foo类型的引用,并将其赋值给一个具有属性"b" Foo类型的新对象。 
Foo b = new Foo("b");
  a = b将引用a NOT f重新分配给其属性为"b"的对象。 
  当您调用modifyReference(Foo c)方法时,会创建一个引用c并将其分配给具有属性"f"的对象。 
 c.setAttribute("c");  将改变引用c点的对象的属性,并且引用f指向它的是同一个对象。 
我希望你现在能理解如何将对象作为参数传递给Java。
链接地址: http://www.djcxy.com/p/49.html上一篇: Is Java "pass
