Java Evaluation Strategy

Java Evaluation Strategy

基础概念

Parameter: 形式参数,是在定义函数时使用的参数,用于在函数体内部接收调用该函数时传入的值;例如在def foo(a:int): int 中称 a为形参
Argument: 实际参数,在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为实际参数;例如在 y = foo(x) 中称 x 为实参

在计算机科学中,求值策略(英语:Evaluation strategy)是确定编程语言中表达式的求值的一组(通常确定性的)规则。重点典型的位于函数或算子上——求值策略定义何时和以何种次序求值给函数的实际参数,什么时候把它们代换入函数,和代换以何种形式发生。经常使用用来研究函数的形式系统 λ 演算来建模求值策略,这里它们通常叫做归约策略。求值策略分为两大基本类,严格的和非严格的,基于如何处理给函数的实际参数
from wikipedia

Call By Value or Reference

Pass By Value: 值传递,是指在调用函数时将实际参数复制一份传递到函数中;在函数中如果对参数进行修改,将不会影响到实际参数。

  • In Pass by value, the function is called by directly passing the value of the variable as an argument. So any changes made inside the function do not affect the original value.
  • In Pass by value, parameters passed as arguments create their own copy. So any changes made inside the function are made to the copied value not to the original value

Pass by Reference: 引用传递,是指在调用函数时将实际参数的地址直接传递到函数中,在函数中对参数所进行的修改,将影响到实际参数。

  • In Pass by reference, Function is called by directly passing the reference/address of the variable as an argument. So changing the value inside the function also change the original value. In JavaScript array and Object follows pass by reference property.
  • In Pass by reference, parameters passed as an arguments does not create its own copy, it refers to the original value so changes made inside function affect the original value.

Java 中的参数传递

那么为什么在 Java 中只有 call by value 呢?

这主要是因为 Java 中的所有参数传递都是通过值传递的。在 Java 中,对象引用作为参数传递时,实际上是将对象在堆 Heap中地址值拷贝一份传递给函数,而不是对象本身。基本类型的参数传递也是如此,传递的是基本类型字面量值的 copy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Test {
    public static void main(String[] args) {
        int x = 10;
        changePrimitive(x);
        System.out.println(x);  // 输出 10,因为 x 的值没有被改变

        Integer y = new Integer(10);
        changeReference(y);// num 是 y 的copy
        System.out.println(y);  // 输出 10

        int[] z = {10};
        changeArray(z);// num 为 z 的 copy
        System.out.println(z[0]);  // 输出 20,因为 z[0] 的值被改变
    }

    public static void changePrimitive(int num) {
        num = 20;
    }

    public static void changeReference(Integer num) {
        num = new Integer(20);//num本来指向y对象,现在指向另一个Integer对象,此后num和y没有任何关系.
    }

    public static void changeArray(int[] num) {
        num[0] = 20;
    }
}
作者

Jiaxing Gao

发布于

2024-02-01

更新于

2024-11-16

许可协议

评论

}