• Java方法传递参数传值还是传址的问题


    这几天重构项目代码遇到一个疑问:可不可以在方法A中定义一个boolean变量b为false,然后A调用方法C把b传递到C方法中经过一些列业务判断后修改为true,C执行结束后A方法中b的值还是原来的false而并不会取到C方法修改后的true(当然实际业务并不是这样写,只是有这个疑问)。

    查了一下资料,结论是这关系到Java方法传递参数是传值还是传址,方法执行的时候会不会拷贝副本再使用的问题。

    回答是 ①Java方法传递传值不传址;②参数传递到方法之后会先进行一份拷贝,方法中使用的是参数的拷贝而参数本身。

    示例代码如下:

    import domain.User;
    
    /**
     * @author cc
     * java 方法执行时传参数是传值,然后拷贝一个副本,方法中修改的是拷贝的副本,并不是值本身
     * 
     * 当参数是引用类型时,传的值是引用的值,不是对象的值。拷贝一份引用的副本,副本的值和原来的值相等
     * 也就是说副本指向的对象和原值指向的是同一个对象
     */
    public class PassValueTest
    {
        
        public static void main(String[] args)
        {
            PassValueTest p = new PassValueTest();
            final int i = 1;
            boolean b = true;
            
            System.out.println("===测试int类型参数会拷贝副本后使用" );
            System.out.println("原来i=" + i);
            p.changeI(i);
            System.out.println("在调用changeI之后 i = " + i);//i的值没有被改变
            System.out.println();
            
            System.out.println("===测试boolean类型参数会拷贝副本后使用" );
            System.out.println("原来b=" +b);
            p.changeB(b);
            System.out.println("在调用changeB之后b = " + b);
            System.out.println();
            
            System.out.println("===测试引用类型参数传递的是引用的值并拷贝副本后使用 ");
            User user = new User("dd", 28);
            p.changeUser(user);
            System.out.println("在调用ChangeUser方法之后user:" + user);
            System.out.println();
            
            System.out.println("===测试引用类型参数传到方法里面后是否会被先拷贝副本");
            User userA = new User("userA", 10);
            User userB = new User("userB", 12);
            
            p.changeCopy(userA, userB);
            
            System.out.println("在调用changeCopy方法之后,实际上userA和userB并没有改变:userA: " + userA
                    +",userB:" + userB);//实际上userA 和userB的引用并没有被改变
            System.out.println("如果在方法中没有拷贝参数而直接使用参数的话,userA和userB的引用应该会像在方法中被调换的");
        }
        public int  changeI(int i)
        {
            i = i+2;
            System.out.println("在changeI方法中修改后i副本= " + i);
            return i;
        }
        public boolean changeB(boolean b)
        {
            b = false;
            System.out.println("在changeB方法中修改后b副本= " + b);
            return b;
        }
        
        public void changeUser(User user)
        {
            System.out.println("在changeUser方法中,user参数副本指向的对象和user参数指向的对象是同一个对象,修改前user:" + user);
            user.setName("cici");
            user.setAge(18);
            System.out.println("在changeUser方法中,修改了参数副本所指向对象的值,修改后user:" + user);
        }
        
        public void changeCopy(User userA,User userB)
        {
            System.out.println("在方法changeCopy中UserA和UserB的引用副本在修改前是 ,userA副本 :" 
                    + userA +", userB副本 : " + userB);
            User temp = userA;//把A引用副本赋值给temp,就是说temp引用指向A对象
            userA = userB;//把B引用副本赋值给A引用副本,就是说此时A引用副本指向B对象
            userB = temp;//把temp引用赋值给B引用副本,就是说此时B引用副本指向A对象
            
            System.out.println("在方法changeCopy中UserA和UserB的引用副本已经被调换 ,userA副本 :" 
            + userA +", userB副本 : " + userB);
        }
    }
    View Code

    用到的User类:

     1 package domain;
     2 
     3 public class User {
     4     private String name;
     5     private int age;
     6     
     7     public User(String name,int age) {
     8         this.name = name;
     9         this.age = age;
    10     }
    11 
    12     public String getName() {
    13         return name;
    14     }
    15 
    16     public void setName(String name) {
    17         this.name = name;
    18     }
    19 
    20     public int getAge() {
    21         return age;
    22     }
    23 
    24     public void setAge(int age) {
    25         this.age = age;
    26     }
    27 
    28     @Override
    29     public String toString() {
    30         StringBuilder builder = new StringBuilder();
    31         builder.append("[").append(name).append(", age=").append(age)
    32                 .append("]");
    33         return builder.toString();
    34     }
    35     
    36     
    37 }
    View Code

    运行结果:

  • 相关阅读:
    第一节:SpringMVC概述
    SpringMVC【目录】
    Windows 系统快速查看文件MD5
    (error) ERR wrong number of arguments for 'hmset' command
    hive使用遇到的问题 cannot recognize input
    Overleaf支持的部分中文字体预览
    Understanding and Improving Fast Adversarial Training
    Django2实战示例 第十三章 上线
    Django2实战示例 第十二章 创建API
    Django2实战示例 第十一章 渲染和缓存课程内容
  • 原文地址:https://www.cnblogs.com/cici20166/p/6503422.html
Copyright © 2020-2023  润新知