Java 显然是按值传递,但需要一些说明

Java is clearly a pass by value but wanted some clarification

阅读了很多关于这个主题的堆栈溢出答案,我也阅读了很多博客。我可以肯定地得出结论,Java 是按值传递的。

但是为了说服人们,我需要一些语言的证明,该证明已通过 ref.

所以有人可以给出一个通过引用传递的语言的实例,我们可以将 java 不是通过引用传递的例子联系起来。

我不知道有什么语言一直是按引用传递的,但 C# 有 ref 修饰符,它允许特定参数使用按引用传递。这使您可以很容易地看到差异。例如:

using System;

public class Program
{
    static void Main()
    {
        string x = "original x";
        string y = "original y";
        Modify(x, ref y);
        Console.WriteLine(x);
        Console.WriteLine(y);
    }

    static void Modify(string px, ref string py)
    {
        px = "modified x";
        py = "modified y";
    }
}

输出为

original x
modified y

这是因为对 px 的赋值不会影响调用代码中的 xxvalue 被传递给方法。但是对 py 的赋值确实 改变了 y,因为 y 是通过引用 传递的 pyy 基本上是同一存储位置的别名。

所有这些只有在您修改参数本身时才有意义。将上面的程序与这个程序进行比较:

using System;
using System.Text;

public class Program
{
    static void Main()
    {
        StringBuilder x = new StringBuilder("original x");
        Modify(x);
        Console.WriteLine(x);
    }

    static void Modify(StringBuilder px)
    {
        px.Length = 0;
        px.Append("modified x");
    }
}

现在 Modify 方法根本不会更改 px 的值 - 而不是更改 px 的值所引用的对象。不需要按引用传递 - x 的值通过值 传递给方法 ,然后复制到 px。这就像在一张纸上抄下您的家庭住址并将其交给某人。它不是复制房子本身 - 它只是复制 到达 房子的方式。如果你给纸的人去把前门漆成红色,那么当你回家时你会看到这种变化。

这就是为什么了解 variables, objects and references.

之间的区别很重要的原因

C++ 有不同的参数传递方式。一种方法是将指针类型指定为参数。我认为这与 Java 的作用很接近。指针按值传递。您可以修改指针引用的对象的状态,但不能更改调用函数引用的对象实例。

我包含了一个带有两个函数的 C++ 示例。一个具有按值调用的函数和一个具有按引用语义调用的函数。具有按引用调用语义的函数可以更改调用函数正在引用的对象实例。

#include <iostream>

using namespace std;

class ClassA
{

public:
    int a = 0;

};

void funcByValue(ClassA *param)
{
    param->a = 1;
    param = new ClassA();
}

void funcByReference(ClassA* &param)
{
    param->a = 1;
    param = new ClassA();
}


int main()
{
    ClassA *objectA = new ClassA();

    cout << objectA->a << "\n";     //1
    cout << objectA << "\n";        //0000002B1D355AF0

    //This call changes objectA's state
    funcByValue(objectA);
    cout << objectA->a << "\n";     //1
    cout << objectA << "\n";        //0000002B1D355AF0

    //This call changes the object objectA is referencing
    funcByReference(objectA);
    cout << objectA->a << "\n";     //0
    cout << objectA << "\n";        //0000002B1D345610
}

Java 是按值传递: 最好的例子:
http://www.javaworld.com/article/2077424/learn-java/does-java-pass-by-reference-or-pass-by-value.html

C++ 是按引用传递的,也是按值传递的:
http://www.tech-recipes.com/rx/1232/c-pointers-pass-by-value-pass-by-reference/

So can someone give a live example of a language which is pass by reference by whose example we could relate that java is not pass by reference

引用传递与值传递的最佳示例是交换。

void swap(String a, String b) {
    String c = b;
    b = a;
    a = c;
}

void main() {
    String a = "A";
    String b = "B";
    swap(a, b);
    System.out.println(a); // A
    System.out.println(b); // B
}

在这种情况下,虽然变量 main.a 指向与 swap.a 相同的对象,但您有两个对字符串 "A".

的引用

vs C# (IDE One) 支持 by-ref.

void Swap(ref string a, ref string b) {
    string c = b;
    b = a;
    a = c;
}
void main() {
    string a = "A";
    string b = "B";
    Swap(ref a, ref b);
    Console.WriteLine(a); // B
    Console.WriteLine(b); // A
}

在这种情况下,变量 main.a 和 swap.a 是相同的引用,因此对 swap.a 的更改也会发生在 main.a。

那么这与

有何不同
void swap(StringBuilder a, StringBuilder b) {
    String a1 = a.toString();
    String b1 = b.toString();
    a.setLength(0);
    a.append(b1);
    b.setLength(0);
    b.append(a1);
}

void main(){
    StringBuilder a = new StringBuilder("A");
    StringBuilder b = new StringBuilder("B");
    swap(a, b);
    System.out.println(a); // B
    System.out.println(b); // A
}

在这种情况下,指向的对象会发生变化。例如:

public static void main(String... agv){
    StringBuilder a = new StringBuilder("A");
    StringBuilder b = new StringBuilder("B");
    StringBuilder alsoA = a;
    swap(a, b);
    System.out.println(a); // B
    System.out.println(b); // A
    System.out.println(alsoA); //B
}

与 C# 中的对比 (IDEOne)

void Main() {
    string a = "a";
    string b = "b";
    string alsoA = a;
    Swap(ref a, ref b);
    Console.WriteLine(a); // B
    Console.WriteLine(b); // A
    Console.WriteLine(alsoA); // A
}

Java 如果您仍然不确定,Ranch 有 good article