• JAVA传值和传引用的区别


    1.基本概念

    1.1 传值

    传递的是值的副本。方法中对副本的修改,不会影响到调用方,也就是不会影响原来的值;

    1.2 引用

    传递的是引用的副本,共用一个内存,会影响到调用方。此时,形参和实参指向同一个内存地址。

    但是对引用副本本身(对象地址)的修改,如设置为null,重新指向其他对象不会影响到调用方

    2.验证

    2.1 基本数据类型

    1.    /**
    2.     * 基本数据类型
    3.     */
    4.    @Test
    5.    public void test2(){
    6.        int value = 1;
    7.        log.info("当前值:{}",value);
    8.        change(value);
    9.        log.info("最终值:{}",value);
    10.   }
    11.    private void change(int value) {
    12.        value = 100*value;
    13.   }

    执行结果

    1. 当前值:1
    2. 最终值:1

    总结

    从输出的的结果中可以看到原本的value并没有被修改,即传值传递的是值的副本,不会影响到本身。

    2.2 引用数据类型

    对象

    1. package com.kang.webservice.pojo;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Data;
    4. import lombok.NoArgsConstructor;
    5. @Data
    6. @AllArgsConstructor
    7. @NoArgsConstructor
    8. public class User {
    9.    private Integer id;
    10.    private String userId;
    11.    private String userName;
    12.  
    13. }
      
    1. /**
    2.     * 引用数据类型
    3.     */
    4.    @Test
    5.    public void test3(){
    6.        log.info("=========================对象================================");
    7.        User user = new User(4, "tom", "汤姆");
    8.        log.info("当前值:{}",user);
    9.        changeObject(user);
    10.        log.info("最终值:{}",user);
    11.        log.info("=========================数组================================");
    12.        List list = new ArrayList<>();
    13.        list.add(1);
    14.        list.add(2);
    15.        list.add(3);
    16.        list.add(4);
    17.        log.info("当前值:{}",JSON.toJSONString(list));
    18.        changeList(list);
    19.        log.info("最终值:{}",JSON.toJSONString(list));
    20.        log.info("=========================Map================================");
    21.        Map map = new HashMap<>();
    22.        map.put("user",new User(2,"66","测试01"));
    23.        log.info("当前值:{}",JSON.toJSONString(map));
    24.        changeMap(map);
    25.        log.info("最终值:{}",JSON.toJSONString(map));
    26.   }
    27.    private void changeMap(Map map) {
    28.        User user = map.get("user");
    29.        user.setUserId("没有赎金惨遭撕票");
    30.   }
    31.    private void changeList(List list) {
    32.        list.remove(1);
    33.        list.add(5);
    34.   }
    35.    private void changeObject(User user) {
    36.        user.setUserId("我被不发份子绑票了");
    37.   }

    执行结果

    1. 14:44:41.149 [main] INFO com.kang.webservice.DemoTest - =========================对象================================
    2. 14:44:41.151 [main] INFO com.kang.webservice.DemoTest - 当前值:User(id=4, userId=tom, userName=汤姆)
    3. 14:44:41.159 [main] INFO com.kang.webservice.DemoTest - 最终值:User(id=4, userId=我被不发份子绑票了, userName=汤姆)
    4. 14:44:41.159 [main] INFO com.kang.webservice.DemoTest - =========================数组================================
    5. 14:44:41.208 [main] INFO com.kang.webservice.DemoTest - 当前值:[1,2,3,4]
    6. 14:44:41.209 [main] INFO com.kang.webservice.DemoTest - 最终值:[1,3,4,5]
    7. 14:44:41.209 [main] INFO com.kang.webservice.DemoTest - =========================Map================================
    8. 14:44:41.244 [main] INFO com.kang.webservice.DemoTest - 当前值:{"user":{"id":2,"userId":"66","userName":"测试01"}}
    9. 14:44:41.244 [main] INFO com.kang.webservice.DemoTest - 最终值:{"user":{"id":2,"userId":"没有赎金惨遭撕票","userName":"测试01"}}

    总结

    可以看到方法中的引用数据类型的值被修改了,因为传引用后指向的是同一个地址,修改的实际上也就是这个地址上的值,另外要注意一点的是如果对象被重新创建或赋值为null,即new会重新指向其他对象,不影响其原对象的值。

    2.3 传final修饰的String,Integer等类型

    1. public final class String
    2.    implements java.io.Serializable, Comparable, CharSequence,
    3.               Constable, ConstantDesc {
    1. public final class Integer extends Number
    2.        implements Comparable, Constable, ConstantDesc {

     

    1. /**
    2.     * String,Integer,Long
    3.     */
    4.    @Test
    5.    public void test4(){
    6.        log.info("=========================String================================");
    7.        String value = "我是真的美猴王";
    8.        log.info("当前值:{}",value);
    9.        changeString(value);
    10.        log.info("最终值:{}",value);
    11.        log.info("=========================Integer================================");
    12.        Integer i = 10;
    13.        log.info("当前值:{}",i);
    14.        changeInteger(i);
    15.        log.info("最终值:{}",i);
    16.   }
    17.    private void changeInteger(Integer i) {
    18.        i = 10000*i;
    19.   }
    20.    private void changeString(String value) {
    21.        value = "你看我几分像从前";
    22.   }

    结果

    1. 14:55:08.815 [main] INFO com.kang.webservice.DemoTest - =========================String================================
    2. 14:55:08.817 [main] INFO com.kang.webservice.DemoTest - 当前值:我是真的美猴王
    3. 14:55:08.818 [main] INFO com.kang.webservice.DemoTest - 最终值:我是真的美猴王
    4. 14:55:08.819 [main] INFO com.kang.webservice.DemoTest - =========================Integer================================
    5. 14:55:08.819 [main] INFO com.kang.webservice.DemoTest - 当前值:10
    6. 14:55:08.819 [main] INFO com.kang.webservice.DemoTest - 最终值:10

    总结

    String、Integer、Double等immutable类型因为类的变量设为final属性,无法被修改,只能重新赋值或生成对象。当Integer作为方法参数传递时,对其赋值会导致原有的引用被指向了方法内的栈地址,失去原有的的地址指向,所以对赋值后的Integer做任何操作都不会影响原有值。

    3.总结

    • 基本类型(byte,short,int,long,double,float,char,boolean)为传值,传的是副本所以不会影响原有的值

    • 对象类型(Object,数组,容器)为传引用,会影响原来的值

    • String、Integer、Double等immutable类型因为类的变量设为final属性,无法被修改,只能重新赋值或生成对象。当Integer作为方法参数传递时,对其赋值会导致原有的引用被指向了方法内的栈地址,失去原有的的地址指向,所以对赋值后的Integer做任何操作都不会影响原有值。

  • 相关阅读:
    CPG 固体支持物研究:Lumiprobe通用 CPG II 型
    记录我常用的linux(centOS)命令
    聊一聊,今年参加软考高级的一些总结
    API接口开发规范
    Unity 中使用波浪动画创建 UI 图像
    OS2.3.9:读者-写者问题
    阿里云增强版实人认证--银行卡要素核验
    java计算机毕业设计学生自购书平台源码+数据库+系统+lw文档+部署
    中国聚合支付行业市场全景调研及投资价值评估研究报告
    用友U8与MES系统API接口对接案例分析
  • 原文地址:https://blog.csdn.net/LuckFairyLuckBaby/article/details/126366486