Java中的求值策略(值传递)和C++中的引用传递、地址传递又有什么不同?

编程语言中有方法间的参数传递,这个传递的策略叫做求值策略。本篇文章将以Java为核心带你彻底区分值传递,引用传递,地址传递的区别。

在Java中,求值策略有两种方式:值传递和引用传递。重要的是理解 Java 中的求值策略实际上都是值传递。

1.值传递(Pass by Value)

当你将一个基本数据类型(如int、float、char等)作为参数传递给方法时,实际上是将该变量的值拷贝传递给方法内部。这意味着在方法内部对参数的修改不会影响到原始变量。

public void modifyValue(int x) {
    x = 10;
}

int num = 5;
modifyValue(num);
System.out.println(num); // 输出 5,原始变量没有改变

2.引用传递(Pass by Reference)的误解

在 Java 中,对象引用也是通过值传递的,而不是真正的引用传递。当你将一个对象引用作为参数传递给方法时,实际上是将对象引用的副本传递给了方法,这个副本仍然指向原始对象。因此,如果在方法内部修改了对象的状态,这些修改将会反映在原始对象上。

class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }
}

public void modifyName(Person person) {
    person.name = "Alice";
}

Person person = new Person("Bob");
modifyName(person);
System.out.println(person.name); // 输出 "Alice",原始对象的状态被修改了
//进入modifyName后,方法里的person和方法外的person都引用Bob这个person对象, person.name = "Alice"改变了这个对象的name属性

再举一个链表的例子:

public class ListNode {
    public ListNode next;
    public int val;
    public ListNode(){

    }
    public ListNode(ListNode next){
        this.next=next;
    }
    public ListNode(ListNode next,int val){
        this.next=next;
        this.val=val;
    }
}
public class Main {
    public static void main(String[] args) {
        ListNode node2=new ListNode(null,2);
        ListNode node1=new ListNode(node2,1);//手动构建一个两个结点的链表:1->2
        move(node1);
        System.out.println(node1.val);//输出结果为1 move方法内的改变并没有反映到node1变量上,因为head只是node1的一份拷贝
    }
    public static void move(ListNode head){
        head=head.next;
    }
}
//在进入move后,head和node1都引用链表中的第一个结点,head=head.next改变的只是head

在这个例子中,你可以将该次求值策略类比为C++中的引用传递,转化成C++代码大概就是这个样子:

public void move(ListNode &head){
        head=head.next;
    }

但绝不是地址传递:

public  void move(ListNode *head){
        head=head.next;
    }

 如果是C++中的地址传递,那在本例中输出结果将为2。node1就指向了链表中第二个结点。

注意理解和体会引用传递,地址传递的含义和区别

(注:本人不是专门搞C++,明白我想表达的意思就好,如果类比有瑕疵,也欢迎指出错误)

如果你再仔细看一下的话,你会发现两个例子为什么一个改变反映到了原变量上,而另一个改变没有反映到原变量上?

答案是modifyName方法中修改的是对象的属性,move方法中修改的是对象本身。

总结一下

在Java中,无论是基本数据类型还是引用数据类型,都是通过值传递的方式传递给方法。对于基本数据类型,传递的是值的拷贝,对于对象引用,传递的是引用的拷贝。如果方法内部修改了参数的值(无论是基本数据类型的值还是对象引用的值),这些修改都不会影响原始变量或对象的值。但是,如果方法内部修改了对象的状态(通过引用),这些修改将会反映在原始对象上。

说了那么多,总之一句话,在Java中不管是基本类型还是引用类型,方法中的形参都是实参拷贝的一份副本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值