欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java中的值传递和引用传递

程序员文章站 2022-07-14 18:23:54
...

因为在工作中踩过这方面的坑,所以整理了一下这方面的知识。
首先需要注意的是java中是没有指针的,这是和C语言一个很大的不同;其次java中只存在值传递!!!,包括对象(数组,类,接口)等传递的也是引用的地址值,所以还是按值传递。

/**
 * Created by xyc on 2017/4/30 0030.
 */
public class TestObjectChange {
    public static void main(String[] args) {
        int i = 10;
        System.out.println(i);
        changeInt(i);
        System.out.println(i);
        System.out.println("-------------------------------------");
        String s = "10";
        System.out.println(s);
        changeString(s);
        System.out.println(s);

        System.out.println("=====================================");

        User user = new User("张三");
        System.out.println(user.getUserName());
        changeObject(user);
        System.out.println(user.getUserName());
        System.out.println("-------------------------------------");
        System.out.println(user.getUserName());
        changeObjectField(user);
        System.out.println(user.getUserName());

        System.out.println("=====================================");

        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        System.out.println(list.get(0));
        changeList(list);
        System.out.println(list.get(0));
    }

    /**
     * 传递的是值的一份拷贝
     * @param i
     */
    private static void changeInt(int i){
        i = 50;
    }

    /**
     * String类是final修饰的,不可变长字符串,
     * 传递的也是值的一份拷贝
     * @param s
     */
    private static void changeString(String s){
        s = s+"50";
    }

    /**
     * 这里的入参其实是main方法中变量user的引用拷贝,
     * 所以在此方法中改变对象并木有神马卵用
     * @param user
     */
    private static void changeObject(User user){
        user = new User("李四");
    }

    /**
     * 同changeObject一样的道理,
     * 这里的入参也是main方法中变量user的引用拷贝,
     * 但是入参user指向的userName属性确是真实地址,所以可以改变
     * @param user
     */
    private static void changeObjectField(User user){
        if (user != null){
            user.setUserName("李四");
        }
    }

    /**
     * 这里的入参是main方法中变量list的引用拷贝
     * 所以改变它自己是不行的,但可以改变其内部元素,
     * 因为就算是拷贝的引用,但它指向的是真实地址
     * @param list
     */
    private static void changeList(List<Integer> list){
//        list = new ArrayList<>(); 如果这样写的话和changeObject一致,是不会改变list的
        if (list!=null && !list.isEmpty()){
            list.set(0,50);
        }
    }

    static class User{
        private String userName;

        public User(String userName) {
            this.userName = userName;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }
    }
}

对于以上代码我们知道对基本数据类型来说值传递是很好理解的,但是对于对象来说就有点难理解了。
java中的值传递和引用传递
对于对象来说,调用方法时传递的是引用的拷贝,但是拷贝的引用中的属性指向确是真实,所以可以改变对象内的属性值,却无法改变自己的引用值。举个例子,就像你有一把钥匙可以打开一扇门,现在调用方法就相当于你复制了这把钥匙,虽然这把钥匙是复制的,但它也可以打开同样的一扇门,然而你却无法改变这把钥匙,让它打开另一扇门,就算你修改了这把钥匙,要注意你修改的只是复制的钥匙,而原来的钥匙还是没有改变。

参考:http://www.cnblogs.com/coderising/p/5697986.html