zoukankan      html  css  js  c++  java
  • 弄懂Java为何只有值传递

    最近有同学问我关于Java中值传递与引用传递的问题,在此小结一下

    值传递是指在函数调用时将实参内容复制一份传递给形参,这样在函数中改变该参数不会对原参数产生影响。

    引用传递是指将对象地址的引用传递给该函数,这样在函数中改变该参数会对原参数产生影响。

    两者的主要区别在于:是否将实参内容复制一份传递给了形参!

    举个最简单的例子:

    public class test {
        public static void main(String[] args) {
            int num = 10;
            changeNum(num);
            System.out.println(num);
        }
    
        public static void changeNum(int num){
            System.out.println(num);
            num = 20;
            System.out.println(num);
        }
    }

    运行结果如下: 都知道这是值传递,将实参内容10复制一份传递给了该函数,对原参数不产生影响。

    这个例子开始犯迷糊,以为是传递该地址过去 

    public class test {
        public static void main(String[] args) {
            Person p1 = new Person();
            p1.setName("张三");
            p1.setSex("男");
            changePerson(p1);
            System.out.println(p1);
        }
    
        public static void changePerson(Person person){
            person.setName("小花");
            person.setSex("女");
        }
    }
    
    public class Person {
        private String name;
        private String sex;
    
        //省略了getter/setter/toString        
    }

    运行结果如下:我同学在这里犯的迷糊,跟我说是引用传递

    将test类的代码稍加修改加两行代码:

    public class test {
        public static void main(String[] args) {
            Person p1 = new Person();
            p1.setName("张三");
            p1.setSex("男");
            changePerson(p1);
            System.out.println(p1);
        }
    
        public static void changePerson(Person person){
            person = new Person();
            person.setName("小花");
            person.setSex("女");
            System.out.println(person);
        }
    }

    运行结果如下:可见并不是引用传递,如果是引用传递则两次输出结果都改为name=小花,sex=女了。

     还是前面所说:两者的主要区别在于:是否将实参内容复制一份传递给了形参!

    此处还是值传递,复制了实参内容,只不过实参内容是该对象的地址值,注意地址值也是值!

    举个例子:你把你家的钥匙刻了一把给B,B拿着刻印的钥匙去你家打扫卫生,等你回来时发现家里变干净了,你家受到了影响,但你的钥匙并没有受到影响。

    另一个容易对Java值/引用传递犯迷糊的例子:运行结果为:“abc”

    public class test {
        public static void main(String[] args) {
         String s1 = "a"+"b"+"c";
         changeStr(s1);
         System.out.println(s1);
        }
    
        public static void changeStr(String str){
            str+="d";
        }
    }

    关于String类有一点特殊,它是不可变类,建议了解下我之前小结的搞定Java String面试题

    关于字符串中的"+"号:Java有这么一串话:

    java语言提供了字符串串联运算符特殊支持( + ),和其他对象转换为字符串。字符串连接是通过StringBuilder实施(或StringBuffer)类及其append方法。字符串的转换是通过方法toString实施,由Object和继承的所有类的java。

    所以该str+="d"等于String str = new StringBuffer(str).append("d").toString();  

    所以此处相当于新建了一个String对象。

  • 相关阅读:
    主流ORM对比分析,莫人云亦云
    避免远程调用中固有的滞后时间问题的最佳方法是进行更少的调用,并让每个调用传递更多的数据。
    挣值管理(PV、EV、AC、SV、CV、SPI、CPI) 记忆
    项目成本管理记忆口诀:
    总是差和自由时差
    成本基线
    php htmlentities函数的问题
    .NET简谈事务、分布式事务处理
    Startup配置类 居然又是约定
    项目管理的九大只是领域输入,工具和输出
  • 原文地址:https://www.cnblogs.com/zengcongcong/p/11565354.html
Copyright © 2011-2022 走看看