【Java学习记录06】告别误解,Java中真的只有值传递!

  • 在编程语言中(如C、C++),参数传递有两种方式,一种是值传递(值调用 call by value),一种是引用传递(其实就是传递指针 call by reference)。

    • 按值调用指的是方法接受的是调用者的值,一个方法不能修改传递值的那个变量本身的值。
    • 引用调用指的是方法接受的是调用者提供的变量地址(指针),一个方法可以修改传递引用的那个变量本身的值。
  • 方法接受的参数总的来说就是两种类型:

    • 基本数据类型(8种)
    • 引用数据类型
  • 在Java中,参数传递的方式只有值传递。

为什么这么说?请看以下三个实例。

  • 实例1:参数为基本数据类型

    public class TestCallMethod {
        public static void main(String[] args) {
            int x= 10;
            System.out.println("before call method func(), x is "+x);
            func(x);
            System.out.println("after call method func(), x is "+x);
        }
        
        public static void func(int y) {
            y = y * y;
        }
    }
    

    调用func()方法前后,x的值均为10,说明对于基本数据类型采用的是值传递。

  • 实例2:参数为引用数据类型

    import java.util.Date;
    
    public class Employee {
        private String name;
        private double salary = 5000;
        private Date hireDay;
    
        public Employee() {
        }
    
        public Employee(String name, double salary, Date hireDay) {
            this.name = name;
            this.salary = salary;
            this.hireDay = hireDay;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public double getSalary() {
            return salary;
        }
    
        public void setSalary(double salary) {
            this.salary = salary;
        }
    
        public Date getHireDay() {
            return hireDay;
        }
    
        public void setHireDay(Date hireDay) {
            this.hireDay = hireDay;
        }
    
        public void raiseSalary(double byPercent) {
            double raise = salary * byPercent / 100;
            this.salary = this.salary + raise;
        }
    }
    
    
    import java.util.Date;
    
    public class TestCallMethod {
        public static void main(String[] args) {
            Date d = new Date(2020, 9, 6);
            Employee e = new Employee("Tom", 1000, d);
            System.out.println("before call method changeSalary(), salary is "+e.getSalary());
            changeSalary(e);
            System.out.println("after call method changeSalary(), salary is "+e.getSalary());
        }
        
        public static void changeSalary(Employee e) {
            e.raiseSalary(200);
        }
       
    }
    
    • 程序运行结果:

    before call method changeSalary(), salary is 1000;

    after call method changeSalary(), salary is 3000;

    • 说明:
      在这里插入图片描述

    注意:这里执行结果很像是将对象引用按引用传递方式进行参数的传递,但实际的调用过程如上图所示,传递进去的仍然是变量的拷贝,只不过拷贝的变量中值为指向对象的引用(指针),所以方法内通过x变量调用方法修改的也正是原变量所指向的对象的值。

  • 实例3:引用数据类型不是引用传递的,只有值传递

    import java.util.Date;
    
    public class TestCallMethod {
        public static void main(String[] args) {
            Date d = new Date(2020,9,6);
            Employee a = new Employee("Alice", 20000, d);
            Employee b = new Employee("Bob", 20000, d);
            System.out.println("before call method swap(), a.getName() is "+a.getName()+", b.getName() is "+b.getName());
            swap(a,b);
            System.out.println("after call method swap(), a.getName() is "+a.getName()+", b.getName() is "+b.getName());
        }
    
        public static void swap(Employee x, Employee y) {
            Employee temp = x;
            x = y;
            y = temp;
        }
    
    }
    
    
    • 程序执行结果:

    before call method swap(), a.getName() is Alice, b.getName() is Bob

    after call method swap(), a.getName() is Alice, b.getName() is Bob

    • 说明:

    我们在程序中用swap方法交换两个传入的对象引用所指向的对象地址,执行前后发现并不会改变原变量a,b所执行的对象地址,说明Java中引用类型采用的不是引用传递,而是值传递。

    在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值