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

什么是解释?


当前回答

Java 通过值的参数,并且仅值。

短篇小说 短篇小说:

对于来自C#的人来说:没有“外”参数,对于来自PASCAL的人来说:没有“存在”参数。

这意味着你不能从对象本身改变参考,但你总是可以改变对象的属性。

一个工作室是使用 StringBuilder 参数而不是 String。

其他回答

最短的答案:)

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#):通過價值和参考

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 仍然相同。

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

首先,我们应该明白什么是通过值或通过参考的意思。

通过值:方法参数值复制到另一个变量,然后复制的对象通过,这就是为什么它被称为通过值。

public class Balloon {

    private String color;

    public Balloon(){}

    public Balloon(String c){
        this.color=c;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

public class Test {

    public static void main(String[] args) {

        Balloon red = new Balloon("Red"); //memory reference 50
        Balloon blue = new Balloon("Blue"); //memory reference 100

        swap(red, blue);
        System.out.println("red color="+red.getColor());
        System.out.println("blue color="+blue.getColor());

        foo(blue);
        System.out.println("blue color="+blue.getColor());

    }

    private static void foo(Balloon balloon) { //baloon=100
        balloon.setColor("Red"); //baloon=100
        balloon = new Balloon("Green"); //baloon=200
        balloon.setColor("Blue"); //baloon = 200
    }

    //Generic swap method
    public static void swap(Object o1, Object o2){
        Object temp = o1;
        o1=o2;
        o2=temp;
    }
}

当我们执行上述程序时,我们会跟踪输出。

red color=Red
blue color=Blue
blue color=Red

Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");

public static void swap(Object o1, Object o2){ //o1=50, o2=100
    Object temp = o1; //temp=50, o1=50, o2=100
    o1=o2; //temp=50, o1=100, o2=100
    o2=temp; //temp=50, o1=100, o2=50
} //method terminated

如果你已经明白了这一点,你可以轻松地理解混乱的原因. 因为变量只是对物体的参考,我们会感到困惑,我们正在通过参考,所以Java通过参考。

现在,让我们分析 foo() 方法执行。

private static void foo(Balloon balloon) { //baloon=100
    balloon.setColor("Red"); //baloon=100
    balloon = new Balloon("Green"); //baloon=200
    balloon.setColor("Blue"); //baloon = 200
}

第一行是最重要的,当我们称之为一个方法时,该方法在参考位置上被称为对象,在这一点上,气球指向100,因此它的颜色变成红色。

Java 总是通过价值,没有例外,永远。

因此,怎样才能让任何人完全困惑,相信Java是通过参考,或者认为他们有一个Java作为通过参考的例子?关键点是Java从来没有提供直接访问对象本身的价值,在任何情况下。

因此,当呼叫一种方法时

对于原始论点(int、long等)而言,值的过渡是原始的实际价值(例如,3)。

所以,如果你有DoSomething(foo)和公共空白DoSomething(Foo foo) {.. } 两个 Foos 有复制的参考,指向相同的对象。

当然,通过值对一个对象的参考看起来非常相似(并且在实践中不可分辨的)通过对象的参考。

参考是常见的值,无论你使用哪种语言。

(Name)[Location] -> [Value at the Location]
---------------------
(Ref2Foo)[223]  -> 47
(Foo)[47]       -> 5

这就是跳板的工作方式。

在每个例子上创建了一个值 - 一个现有值的副本 - 现在是接收方法来处理它. 当你写“Foo”在方法,它是从EAX,或者自动右转,或双右转,过程取决于语言如何工作和 / 或什么类型的Foo独裁。

现在我们把Foo转到方法:

因此,简而言之,在Java本身的术语中,Java是通过价值,在那里价值可以是:无论是真实的价值还是参考的价值。