一段代码引发的思考——java值传递和引用传递

今天小伙伴问我一段代码:

  public static ListNode create(int[] array) {
        if (array == null || array.length == 0)
            return null;
        ListNode head = new ListNode(0);
        ListNode node = head;
        for (int i = 0; i < array.length; i++) {
            ListNode temp = new ListNode(array[i]);
            node.next = temp;
            node = temp;
            System.out.println(node.val);
        }
        return head.next;
    }

为什么在方法内head指向的是链表的最后一个结点,但是在main方法中head指向的是第一个结点。

我进行了测试



public class Main {

    public static class ListNode{
        int val;
        ListNode next; //下一个链表对象
        ListNode(int x){val=x;}  //赋给结点的值
    }

    public static ListNode create(int[] array) {
        if (array == null || array.length == 0)
            return null;
        ListNode head = new ListNode(0);  //预指针,其下一个结点指向真正的头结点
        ListNode node = head;
        for (int i = 0; i < array.length; i++) {
            ListNode temp = new ListNode(array[i]);
            node.next = temp;
            node = temp;
            System.out.println(node.val);
        }
        return head.next;
    }

    public static void main(String[] args)
    {
        int[] array={1,2,3,4,5,6,7,8,9};
        ListNode a=create(array);
        System.out.println("---------"+a.val);
    }
}

发现真的是a.val输出为1。

后来经过一波讨论,查阅了很多资料得出一下结论。

这是因为ListNode a=create(array);被初始化,将head.next的初值1赋值给了a。然后再执行create方法。但由于java的引用传递,虽然方法内head的最后的值变为9,但是最后赋值给a的值依然为其初始值1。

值传递:
在方法被调用时,实参通过形参把它的内容副本传入方法内部,此时形参接收到的内容是实参值的一个拷贝,因此在方法内对形参的任何操作,都仅仅是对这个副本的操作,不影响原始值的内容。

引用传递:
引用也就是指向真实内容的地址值,在方法调用时,实参的地址通过方法调用被传递给相应的形参,在方法体内,形参和实参指向内存地址,对形参的操作会影响的真实值。

JVM内存模型中,方法是存在虚拟栈中的,一个线程独享一个栈,而堆和方法区是所有线程共享的。JAVA的引用传进函数时 , 会复制一个引用与实参指向同一对象的引用, 操作的不是同一个引用。如下图所示:

总的来说就是只有当变量本身的值发生改变,值才会改变。

发布了47 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/floraruo/article/details/104045290