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

什么是解释?


当前回答

您可以通过值(4,5) 您可以通过地址(0xF43A)

Point p = Point(4,5);

Point *x = &p;

它保留了 4 位比特,并存储了 0xF43A。

Point &y = p;

它保留了 4 位比特,并存储了 0xF43A。

在指标的情况下,你必须使用 -> 访问会员,在参考情况下你必须使用.. 如果你想交换原始的值,那么你可以做 tmp=a; a=b; b=tmp;在参考情况下和 tmp=*a; *b=tmp; *a=tmp为指标。

因此,Java通过原始值和对象的参考值,Java复制值来实现这一点,但C++是这样做的。

为了完整性:

Point p = new Point(4,5);

如果你想改變記憶體位置這樣

void swap(int& a, int& b) {
    int *tmp = &a;
    &a = &b;
    &b = tmp;
}

然后你会发现你走进你的硬件的限制。

其他回答

Java 总是使用 Call by Value. 这意味着该方法获得所有参数值的副本。

考虑下列三种情况:

1、试图改变原始变量

public static void increment(int x) { x++; }

int a = 3;
increment(a);

x 将复制一个值,并将增加 x,一个将保持相同的值

(二)试图改变对象的原始领域

public static void increment(Person p) { p.age++; }

Person pers = new Person(20); // age = 20
increment(pers);

p 将复制个体的参考值,并将增加年龄领域,变量是指相同的对象,所以年龄改变。

(三)试图改变参考变量的参考值

public static void swap(Person p1, Person p2) {
    Person temp = p1;
    p1 = p2;
    p2 = temp;
}

Person pers1 = new Person(10);
Person pers2 = new Person(20);
swap(pers1, pers2);

呼叫交换 p1 后,p2 复制 pers1 和 pers2 的参考值与值交换,因此 pers1 和 pers2 仍然相同。

因此,您只能在将参考值复制到该对象时更改对象的字段。

查看此代码. 此代码不会扔 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,参数是经过的变量的副本,所有对象都是用参考来定义的,参考是存储一个记忆地址的变量,其中对象在记忆中。

查看评论以了解执行中发生了什么;跟随数字,因为它们显示执行的流动。

class Example
{
    public static void test (Cat ref)
    {
        // 3 - <ref> is a copy of the reference <a>
        // both currently reference Grumpy
        System.out.println(ref.getName());

        // 4 - now <ref> references a new <Cat> object named "Nyan"
        ref = new Cat("Nyan");

        // 5 - this should print "Nyan"
        System.out.println( ref.getName() );
    }

    public static void main (String [] args)
    {
        // 1 - a is a <Cat> reference that references a Cat object in memory with name "Grumpy"
        Cat a = new Cat("Grumpy");

        // 2 - call to function test which takes a <Cat> reference
        test (a);

        // 6 - function call ends, and <ref> life-time ends
        // "Nyan" object has no references and the Garbage
        // Collector will remove it from memory when invoked

        // 7 - this should print "Grumpy"
        System.out.println(a.getName());
    }
}

Java 以值传输对象的参考。

Java 总是通过值,而不是通过参考。

Pass by reference(也称为 pass by address)是指实际参数地址的副本存储。

public class PassByValue {
    public static void main(String[] args) {
        Test t = new Test();
        t.name = "initialvalue";
        new PassByValue().changeValue(t);
        System.out.println(t.name);
    }
    
    public void changeValue(Test f) {
        f.name = "changevalue";
    }
}

class Test {
    String name;
}

让我们一步一步了解一下:

Test t = new Test();

正如我们都知道,它将创建一个对象,并将参考值返回t 例如,假设t 的值为 0x100234 (我们不知道实际的 JVM 内部值,这只是一个例子) 。

此分類上一篇

new PassByValue().changeValue(t);

通过 t 函数时,它不会直接通过对象测试的实际参考值,但它会创建 t 的副本,然后将其转移到函数。 因为它通过值,它会通过变量的副本而不是实际的参考值。 因为我们说 t 的值是 0x100234, t 和 f 都将具有相同的值,因此它们将指向相同的 ob。

此分類上一篇

public class PassByValue {
    public static void main(String[] args) {
        Test t = new Test();
        t.name = "initialvalue";
        new PassByValue().changeRefence(t);
        System.out.println(t.name);
    }
    
    public void changeRefence(Test f) {
        f = null;
    }
}

class Test {
    String name;
}

这会扔一个NullPointerException吗? 不,因为它只通过一个副本的参考。 在通过参考的情况下,它可能会扔一个NullPointerException,如下所示:

此分類上一篇

希望这能帮助。