• 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

    运行结果:

  • 相关阅读:
    BootStrap 模态框禁用空白处点击关闭
    【云计算】使用nsenter进入Docker容器进行调试
    【架构】Nginx如何设置X-Request-ID请求头,记录请求时间:毫秒?
    【架构】微服务系列文章
    【云计算】OpenStack项目全面介绍
    【云计算】CloudFoundry参考资料
    【云计算】OpenShift容器服务参考
    【Web】Django OAuth invalid_grant error
    【Linux】Shell三类变量的作用域——linux shell “永久环境变量”、“临时环境变量”和"普通变量"之完全解读
    【云计算】OpenStack Horizon DashBoard定制化,完整实现前后台交互
  • 原文地址:https://www.cnblogs.com/cici20166/p/6503422.html
Copyright © 2020-2023  润新知