01-Java程序设计语言是按值调用还是按引用调用?

01-Java程序设计语言是按值调用还是按引用调用?

在写代码过程中,我们经常会将基本类型作为参数传递给一个方法;或者将一个对象作为参数传递给一个方法。这样的方式思考,好像是既有按值调用又有按引用调用;

其实上面的回答是错误的;Java程序设计语言是按值调用,即方法得到所有参数值的一个副本;那么下面我们分析下为什么没有按引用调用

概念

  • 按值调用:方法接收的是调用者提供的值;该值是参数的副本(复制一份数据操作)
  • 按引用调用:方法接收的是调用者提供的变量地址(直接操作源文件)

注意两者区别:按值调用是 参数副本;按引用调用 直接操作源文件;

例子

package com.dwb.snail.day.day01;

/**
 * @Description javac程序设计是按值传递
 * @Date 2020/10/8 11:32 PM
 * @Created by dwb
 * 微信: snail_java
 */
public class CallByReference {


    public static void main(String[] args) {

        int a = 20;
        System.out.println("基本类型调用前:" + a);
        changeValue(a);
        System.out.println("基本类型调用后:" + a);

        Student student = new Student(18, "小明");
        System.out.println("引用类型调用前:" + student);
        System.out.println("引用类型调用前学生年龄:" + student.getAge());
        changeStudent(student);
        System.out.println("引用类型调用后:" + student);
        System.out.println("引用类型调用后学生年龄:" + student.getAge());

    }

    private static void changeValue(int a) {
        a = 10;
    }

    private static void changeStudent(Student student) {
        student.setAge(10);
        student.setName("小红");
    }

    private static class Student{
        int age;
        String name;

        public Student(int age, String name) {
            this.age = age;
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }
}

输出:

基本类型调用前:20
基本类型调用后:20

引用类型调用前:com.dwb.snail.day.day01.CallByReference$Student@61bbe9ba

引用类型调用前学生年龄:18

引用类型调用后:com.dwb.snail.day.day01.CallByReference$Student@61bbe9ba
引用类型调用后学生年龄:10

基本类型没有变化是可以理解的,因为我操作的是参数传过来的20,原来的20没有变化是对的;但是引用类型,学生的年龄变化了啊,输出的学生对象(默认是地址)没有变化;不应该是按引用调用吗?

这时候我们需要结合jvm堆栈理解

  • Java虚拟机栈描述的是Java方法执行的内存模型:每个方法执行的同时会创建一个栈帧

  • 栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构。它是虚拟机运行时数据区中的java虚拟机栈的栈元素

  • 栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息

01-Java按值调用.png

每个方法的运行都会创建一个栈帧;该栈帧存放参数的值;如果是基本类型,则拷贝基本类型值的副本到栈帧中;如果是引用类型,则拷贝引用类型的引用副本到栈帧中,都是创建了副本到栈帧中,所以java程序设计是按值调用

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。