language-agnostic - 按引用传递还是按值传递?

标签 language-agnostic oop parameters pass-by-reference pass-by-value

学习一门新的编程语言时,您可能遇到的障碍之一是该语言默认情况下是按值传递还是按引用传递。 p>

所以这是我用你们最喜欢的语言向你们所有人提出的问题,它实际上是如何完成的? 可能的陷阱是什么?

当然,您最喜欢的语言可以是您曾经使用过的任何语言:popular , obscure , esoteric , new , old ...

最佳答案

这是我自己对 Java programming language 的贡献.

首先是一些代码:

public void swap(int x, int y)
{
  int tmp = x;
  x = y;
  y = tmp;
}

调用此方法将导致以下结果:

int pi = 3;
int everything = 42;

swap(pi, everything);

System.out.println("pi: " + pi);
System.out.println("everything: " + everything);

"Output:
pi: 3
everything: 42"

即使使用“真实”对象也会显示类似的结果:

public class MyObj {
    private String msg;
    private int number;

    //getters and setters
    public String getMsg() {
        return this.msg;
    }


    public void setMsg(String msg) {
        this.msg = msg;
    }


    public int getNumber() {
        return this.number;
    }


    public void setNumber(int number) {
        this.number = number;
    }

    //constructor
    public MyObj(String msg, int number) {
        setMsg(msg);
        setNumber(number);
    }
}

public static void swap(MyObj x, MyObj y)
{
    MyObj tmp = x;
    x = y;
    y = tmp;
}

public static void main(String args[]) {
    MyObj x = new MyObj("Hello world", 1);
    MyObj y = new MyObj("Goodbye Cruel World", -1); 

    swap(x, y);

    System.out.println(x.getMsg() + " -- "+  x.getNumber());
    System.out.println(y.getMsg() + " -- "+  y.getNumber());
}


"Output:
Hello world -- 1
Goodbye Cruel World -- -1"

因此很明显,Java 按值传递其参数,作为 pieverything 以及 MyObj 对象的值 没有被交换。 请注意,“按值”是 java 中将参数传递给方法的唯一方式。 (例如,像 c++ 这样的语言允许开发人员在参数类型后使用“&”通过引用传递参数)

现在是棘手的部分,或者至少是会让大多数新的 java 开发人员感到困惑的部分:(借自 javaworld )
原作者:托尼·辛特斯

public void tricky(Point arg1, Point arg2)
{
    arg1.x = 100;
    arg1.y = 100;
    Point temp = arg1;
    arg1 = arg2;
    arg2 = temp;
}
public static void main(String [] args)
{
    Point pnt1 = new Point(0,0);
    Point pnt2 = new Point(0,0);
    System.out.println("X: " + pnt1.x + " Y: " +pnt1.y); 
    System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
    System.out.println(" ");
    tricky(pnt1,pnt2);
    System.out.println("X: " + pnt1.x + " Y:" + pnt1.y); 
    System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);  
}


"Output
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0"

tricky成功更改了pnt1的值! 这意味着对象是通过引用传递的,但事实并非如此! 正确的说法是:对象引用是按值传递的。

托尼·辛特斯的更多内容:

The method successfully alters the value of pnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! This is the major source of confusion. In the main() method, pnt1 and pnt2 are nothing more than object references. When you pass pnt1 and pnt2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references. Figure 1 below shows two references pointing to the same object after Java passes an object to a method.

figure 1
(来源:javaworld.com)

结论或长话短说:

  • Java 按值传递参数
  • “按值”是java中将参数传递给方法的唯一方式
  • 使用作为参数给出的对象的方法将改变对象,因为引用指向原始对象。 (如果该方法本身改变了一些值)

有用的链接:

关于language-agnostic - 按引用传递还是按值传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2027/

相关文章:

algorithm - 鉴于您知道发生了某些变化,如何推断未知变量的状态?

language-agnostic - 从 Outlook 2007 中提取自动完成电子邮件

python - 将程序从 FreeBASIC 转换为 Python : globalizing variables

python - API 中对象启动的 OO 设计模式

html - 如何为复选框值构建 url 参数

python - ctypes 结构中的默认值

language-agnostic - 如何重构一个庞大而困惑的代码库?

algorithm - 找出交易量最高的十大公司

c# - oo-spaghettio 网络架构

c++ - QList 默认参数错误消息(QList<QVariant> 的默认参数类型为 int)