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

其他回答

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;
    }
}

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

第二步,请记住,当您将对象转移到一种方法时,您将转移到对象参考,而不是对象本身。

现在,想想一个对象的参考/变量是什么:

1. Person person;
2. person = new Person("Tom");
3. changeName(person);
4.
5. //I didn't use Person person below as an argument to be nice
6. static void changeName(Person anotherReferenceToTheSamePersonObject) {
7.     anotherReferenceToTheSamePersonObject.setName("Jerry");
8. }

发生了什么?

变量人是创建的行 #1 它是零的开始. 一个新人对象是创建的行 #2,存储在记忆中,变量人是给予的参考人对象. 也就是说,其地址. 让我们说 3bad086a. 保持对象的地址的变量人是转移到函数行 #3. 在行 #4 你可以听到沉默的声音 查看其地址。

一张照片值得一千个字:

此分類上一篇

请注意,另一个ReferenceToTheSamePersonObject射线是指向对象而不是变量人!

您总是输入参考值的比特的副本!

Java 是 pass-by-value 因为在一个方法中,你可以随心所欲地修改所提到的对象,但无论你尝试多么艰难,你永远不会能够修改过去的变量,这将保持参考(不 p _ _ _ _ _ _ _ )相同的对象,不管是什么!



它是原始值或参考值的副本,如果是原始值,它是价值的比特的副本,如果是对象,它是参考值的副本。

public class PassByCopy{
    public static void changeName(Dog d){
        d.name = "Fido";
    }
    public static void main(String[] args){
        Dog d = new Dog("Maxx");
        System.out.println("name= "+ d.name);
        changeName(d);
        System.out.println("name= "+ d.name);
    }
}
class Dog{
    public String name;
    public Dog(String s){
        this.name = s;
    }
}

使用 Java PassByCopy:

名称= Maxx 名称= Fido

原始粘贴类和线条是不可变的,因此使用这些类型的任何例子都不会像其他类型/对象一样工作。

最短的答案:)

Java 有 pass-by-value (和 pass-reference-by-value.) C# 也有 pass-by-reference

在 C# 中,它是用“out”和“ref”的关键字实现的。

通过参考:变量以一种方式通过,以便在方法内部的重新分配,即使在方法之外也被反映出来。

下面是通过参考(C#)的例子,这个功能在Java中不存在。

class Example
{
    static void InitArray(out int[] arr)
    {
        arr = new int[5] { 1, 2, 3, 4, 5 };
    }

    static void Main()
    {
        int[] someArray;
        InitArray(out someArray);

        // This is true !
        boolean isTrue = (someArray[0] == 1);
    }
}

此分類上一篇: MSDN 圖書館(C#):通過 ref 和 out 的序列

此分類上一篇: MSDN 圖書館(C#):通過價值和参考

原始和对象参考,但对象可以改变,如果它们的界面允许。

当您将对象转移到一个方法时,您正在转移一个参考,并且该对象可以通过方法实施进行修改。

void bithday(Person p) {
    p.age++;
}

对象本身的参考,通过值:你可以重新分配参数,但变化不会反映:

void renameToJon(Person p) { 
    p = new Person("Jon"); // this will not work
}

jack = new Person("Jack");
renameToJon(jack);
sysout(jack); // jack is unchanged

作为效应问题,“p”是参考(对象的指标),不能改变。

原始类型通过值,对象的参考也可以被视为原始类型。

为了回报,一切都通过了价值。