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

运行结果:

原文地址:https://www.cnblogs.com/cici20166/p/6503422.html