JAVA值传递和引用传递方式

 更新时间:2024年11月30日 12:04:20   作者:杉莘  
文章总结:在Java中,处理不可变集合时,直接修改操作会抛出异常,正确的做法是使用可变集合类型,如ArrayList,或者通过流操作(stream().filter())来实现修改,理解Java方法参数的传递方式(值传递)是关键,这决定了如何正确地修改对象的状态

JAVA值传递和引用传递

ps:

碰到一个业务bug,抛出异常UnsupportedOperationException,检查代码发现在调用链中,listA=ImmutableList.of(xxx);导致listA为不可变List,调用retain()方法抛出异常;

// 原始代码
……
listA.retainAll(listB);
// 修改代码1
listA = listA.stream().filter(listB::contains).collector(Collectors.toList);
……

然后我修改:

listA = new ArrayList<>();
listA.add(xxx);
  • 因为处理过程有好几个分支,为了避免后续其他地方有listA=ImmutableList.of(xxx);此类情况,所以我修改了retain为stream().filter();
  • 然后调试发现值listA修改失败;
  • 还原为listA.retainAll(listB);修改成功;

原因

Java方法参数均为值传递

参数为基本类型

public class Main {
    public static void main(String[] args) {
        // 创建一个整数变量并赋值
        int number = 10;
        // 调用方法并将number传递进去
        changeNumber(number);
        // 输出原始变量的值,仍然是10,未被方法改变
        System.out.println(number);  // 输出: 10
    }
    // 定义一个方法,尝试改变参数的值
    public static void changeNumber(int num) {
        num = 20;  // 这里只是改变了方法内部副本的值
    }
}

参数为引用类型

  • 引用类型其实传递到方法的其实是引用地址的值,两个引用变量都指向原对象;
  • 所以object.value = xxx;会修改值;
  • 而object = new Object()其实只是修改了当前方法入参的引用对象,而原对象未被修改
public class Main {
    public static void main(String[] args) {
        // 创建一个对象
        MyObject obj = new MyObject();
        obj.value = 10;
        // 调用方法并将对象传递进去
        changeObject(obj);
        // 输出对象的值,已被方法改变
        System.out.println(obj.value);  // 输出: 20
		// 调用set方法
		setObject(obj);
		 // 输出对象的值,值不变
        System.out.println(obj.value);  // 输出: 20
    }
    public static void changeObject(MyObject obj) {
        obj.value = 20;  // 这里修改的是对象的实际状态
    }
	public static void setObject(MyObject obj) {
        obj= new MyObjectc();  // 这里修改的是对象的实际状态
    }
    
    static class MyObject {
        int value;
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java使用Callable接口实现多线程的实例代码

    Java使用Callable接口实现多线程的实例代码

    这篇文章主要介绍了Java使用Callable接口实现多线程的实例代码,实现Callable和实现Runnable类似,但是功能更强大,具体表现在可以在任务结束后提供一个返回值,Runnable不行,call方法可以抛出异,Runnable的run方法不行,需要的朋友可以参考下
    2023-08-08
  • 使用java NIO及高速缓冲区写入文件过程解析

    使用java NIO及高速缓冲区写入文件过程解析

    这篇文章主要介绍了使用java NIO及高速缓冲区写入文件过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Spring Boot Nacos 实现不停服发布过程详解

    Spring Boot Nacos 实现不停服发布过程详解

    这篇文章主要为大家介绍了Spring Boot Nacos实现不停服发布过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • Java快速排序与归并排序及基数排序图解示例

    Java快速排序与归并排序及基数排序图解示例

    快速排序是基于二分的思想,对冒泡排序的一种改进。主要思想是确立一个基数,将小于基数的数放到基数左边,大于基数的数字放到基数的右边,然后在对这两部分进一步排序,从而实现对数组的排序
    2022-09-09
  • 通过String.intern()方法浅谈堆中常量池

    通过String.intern()方法浅谈堆中常量池

    这篇文章主要介绍了通过String.intern()方法浅谈堆中常量池,在JDK7之前,字符串常量是存在永久带Perm 区的,JDK7开始在将常量池迁移到堆中,这个变化也导致了String的新特性,下面我们慢慢进行介绍。,需要的朋友可以参考下
    2019-06-06
  • Java 中 Map 集合的三种遍历方式小结

    Java 中 Map 集合的三种遍历方式小结

    这篇文章主要介绍了Java 中 Map 集合的三种遍历方式,每种遍历方式结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • java实现冒泡排序算法

    java实现冒泡排序算法

    冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
    2015-04-04
  • 基于Java代码实现数字在数组中出现次数超过一半

    基于Java代码实现数字在数组中出现次数超过一半

    这篇文章主要介绍了基于Java代码实现数字在数组中出现次数超过一半的相关资料,需要的朋友可以参考下
    2016-02-02
  • 熟练掌握Java8新特性之Stream API的全面应用

    熟练掌握Java8新特性之Stream API的全面应用

    Stream是Java8的一大亮点,是对容器对象功能的增强,它专注于对容器对象进行各种非常便利、高效的 聚合操作(aggregate operation)或者大批量数据操作。Stream API借助于同样新出现的Lambda表达式,极大的提高编程效率和程序可读性,感兴趣的朋友快来看看吧
    2021-11-11
  • Javaweb-HttpServletResponse的sendRedirectch重定向方式

    Javaweb-HttpServletResponse的sendRedirectch重定向方式

    这篇文章主要介绍了Javaweb-HttpServletResponse的sendRedirectch重定向方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09

最新评论