我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。

什么是解释?


当前回答

斯科特·斯坦奇菲尔德先生写了一个很好的答案. 这里是你要确认的课堂,他是什么意思:

public class Dog {

    String dog ;
    static int x_static;
    int y_not_static;

    public String getName()
    {
        return this.dog;
    }

    public Dog(String dog)
    {
        this.dog = dog;
    }

    public void setName(String name)
    {
        this.dog = name;
    }

    public static void foo(Dog someDog)
    {
        x_static = 1;
        // y_not_static = 2;  // not possible !!
        someDog.setName("Max");     // AAA
        someDog = new Dog("Fifi");  // BBB
        someDog.setName("Rowlf");   // CCC
    }

    public static void main(String args[])
    {
        Dog myDog = new Dog("Rover");
        foo(myDog);
        System.out.println(myDog.getName());
    }
}

因此,我们从主()一个名叫Rover的狗,然后我们将一个新的地址给我们通过的指标,但最终,狗的名字不是Rover,也不是Fifi,也许不是Rowlf,但Max。

其他回答

Java 通过值的参数,在 Java 中没有参考的选项。

但是,在收集带层,它使用参考内部不暴露于用户。

它是必不可少的,因为它节省了很多的记忆,并提高了速度。

我试图简化上面的例子,只保持问题的本质. 让我把这个作为一个容易记住和正确应用的故事。 故事如下: 你有一个宠物狗,吉米,尾巴长12英寸。

下次你旅行,你带狗,无意中,到一个邪恶的<unk>子,他也是长尾的仇恨者,所以他把它切到一个可怜的2英寸,但他这样做你的亲爱的吉米,而不是一个克隆。

public class Doggie {

    public static void main(String...args) {
        System.out.println("At the owner's home:");
        Dog d = new Dog(12);
        d.wag();
        goodVet(d);
        System.out.println("With the owner again:)");
        d.wag();
        badVet(d);
        System.out.println("With the owner again(:");
        d.wag();
    }

    public static void goodVet (Dog dog) {
        System.out.println("At the good vet:");
        dog.wag();
        dog = new Dog(12); // create a clone
        dog.cutTail(6);    // cut the clone's tail
        dog.wag();
    }

    public static void badVet (Dog dog) {
        System.out.println("At the bad vet:");
        dog.wag();
        dog.cutTail(2);   // cut the original dog's tail
        dog.wag();
    }    
}

class Dog {

    int tailLength;

    public Dog(int originalLength) {
        this.tailLength = originalLength;
    }

    public void cutTail (int newLength) {
        this.tailLength = newLength;
    }

    public void wag()  {
        System.out.println("Wagging my " +tailLength +" inch tail");
    }
}

Output:
At the owner's home:
Wagging my 12 inch tail
At the good vet:
Wagging my 12 inch tail
Wagging my 6 inch tail
With the owner again:)
Wagging my 12 inch tail
At the bad vet:
Wagging my 12 inch tail
Wagging my 2 inch tail
With the owner again(:
Wagging my 2 inch tail
public class Test {

    static class Dog {
        String name;

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Dog other = (Dog) obj;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }

        public String getName() {
            return name;
        }

        public void setName(String nb) {
            this.name = nb;
        }

        Dog(String sd) {
            this.name = sd;
        }
    }
    /**
     * 
     * @param args
     */
    public static void main(String[] args) {
        Dog aDog = new Dog("Max");

        // we pass the object to foo
        foo(aDog);
        Dog oldDog = aDog;

        System.out.println(" 1: " + aDog.getName().equals("Max")); // false
        System.out.println(" 2 " + aDog.getName().equals("huahua")); // false
        System.out.println(" 3 " + aDog.getName().equals("moron")); // true
        System.out.println(" 4 " + " " + (aDog == oldDog)); // true

        // part2
        Dog aDog1 = new Dog("Max");

        foo(aDog1, 5);
        Dog oldDog1 = aDog;

        System.out.println(" 5 : " + aDog1.getName().equals("huahua")); // true
        System.out.println(" part2 : " + (aDog1 == oldDog1)); // false

        Dog oldDog2 = foo(aDog1, 5, 6);
        System.out.println(" 6 " + (aDog1 == oldDog2)); // true
        System.out.println(" 7 " + (aDog1 == oldDog)); // false
        System.out.println(" 8 " + (aDog == oldDog2)); // false
    }

    /**
     * 
     * @param d
     */
    public static void foo(Dog d) {
        System.out.println(d.getName().equals("Max")); // true

        d.setName("moron");

        d = new Dog("huahua");
        System.out.println(" -:-  " + d.getName().equals("huahua")); // true
    }

    /**
     * 
     * @param d
     * @param a
     */
    public static void foo(Dog d, int a) {
        d.getName().equals("Max"); // true

        d.setName("huahua");
    }

    /**
     * 
     * @param d
     * @param a
     * @param b
     * @return
     */
    public static Dog foo(Dog d, int a, int b) {
        d.getName().equals("Max"); // true
        d.setName("huahua");
        return d;
    }
}

样品代码显示对不同功能对对物体的变化的影响。

在这里,每一个单一的答案都倾向于从其他语言中提到通过指标,并显示在Java中不可能做什么,因为任何原因,没有人试图从其他语言中展示如何实施通过对象的价值。

这个代码表明如何做这样的事情:

public class Test
{
    private static void needValue(SomeObject so) throws CloneNotSupportedException
    {
        SomeObject internalObject = so.clone();
        so=null;
        
        // now we can edit internalObject safely.
        internalObject.set(999);
    }
    public static void main(String[] args)
    {
        SomeObject o = new SomeObject(5);
        System.out.println(o);
        try
        {
            needValue(o);
        }
        catch(CloneNotSupportedException e)
        {
            System.out.println("Apparently we cannot clone this");
        }
        System.out.println(o);
    }
}

public class SomeObject implements Cloneable
{
    private int val;
    public SomeObject(int val)
    {
        this.val = val;
    }
    public void set(int val)
    {
        this.val = val;
    }
    public SomeObject clone()
    {
        return new SomeObject(val);
    }
    public String toString()
    {
        return Integer.toString(val);
    }
}

在这里,我们有一个函数需要值,它正在立即创建一个对象的克隆,需要在对象本身的类中实施,而该类必须被标记为克隆。

可能很好,Java没有通过参考语法,但称之为“通过价值”的语言沿着有愿望的思维线。

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通过值的参数到方法,如果变量点到对象的参考,实际对象也会被更改。