【Java】Java的对象参数踩坑总结

文章目录

前言

今天写代码的时候,犯了一个很基础很低级的错误。实在惭愧,在此花点顺手记录一下,养成习惯。

需求是需要把byte[]作为入参的同时,也作为出参,传一个空白的byte[]作为参数,在方法里面修改byte[],修改完毕后,外面方法获取到被修改后的参数,很简单吧。

失败的修改

new 一个byte[],然后改为全零,再打印看看是否成功:

java 复制代码
   @Test
    public void invoke(){
        byte[] bytes = new byte[]{1,2,3};
        System.out.println("before: bytes = " + Arrays.toString(bytes));
        /*changeBytes(bytes);
        System.out.println("after changeBytes: bytes = " + Arrays.toString(bytes));*/

        changeBytes2(bytes);
        System.out.println("after changeBytes2: bytes = " + Arrays.toString(bytes));
    }
    
 private void changeBytes2(byte[] bytes) {
        System.out.println("changeBytes2 before bytes = " + Arrays.toString(bytes));
        bytes = new byte[]{0,0,0};
        System.out.println("changeBytes2 after bytes = " + Arrays.toString(bytes));
    }
    

输出:

bash 复制代码
before: bytes = [1, 2, 3]
changeBytes2 before bytes = [1, 2, 3]
changeBytes2 after bytes = [0, 0, 0]
after changeBytes2: bytes = [1, 2, 3]

可以看到,数组修改失败。

成功的修改

java 复制代码
  @Test
    public void invoke(){
        byte[] bytes = new byte[]{1,2,3};
        System.out.println("before: bytes = " + Arrays.toString(bytes));
        changeBytes(bytes);
        System.out.println("after changeBytes: bytes = " + Arrays.toString(bytes));

        /*changeBytes2(bytes);
        System.out.println("after changeBytes2: bytes = " + Arrays.toString(bytes));*/
    }

    private void changeBytes(byte[] bytes) {
        Arrays.fill(bytes, (byte) 0);
    }

打印结果:

java 复制代码
before: bytes = [1, 2, 3]
after changeBytes: bytes = [0, 0, 0]

bytes数据成功被修改。

原理分析

基本类型参数

在 Java 中,传递给方法的参数是按值传递的,这意味着方法得到的是参数的副本,而不是参数本身。对于基本数据类型,这意味着方法得到的是值的拷贝,对参数的修改不会影响调用者的变量。

对象引用参数

但是对于对象引用(包括数组),方法得到的是引用的拷贝,这意味着方法内部可以修改对象的内容,并且这些修改将影响到调用者持有的引用。所以,无论你传递的是数组、集合对象或者是其他对象,只要你在方法内部修改了这个对象的内容,这些修改都会影响到调用者持有的引用。

举一反三:不修改对象参数怎么写?

如果你想要避免对调用者持有的对象产生影响,可以创建一个新的对象,并将修改后的内容复制到新对象中,然后返回这个新对象。这样调用者将得到一个新的对象,原始对象不会受到影响。

举个例子,如果要修改的是一个字符串对象,你可以使用 StringBuilder 类来构建一个新的字符串:

java 复制代码
private String changeString(String originalString) {
    StringBuilder sb = new StringBuilder(originalString);
    sb.append(" additional content");
    return sb.toString();
}
相关推荐
人工干智能1 天前
Python 开发中:`.ipynb`(Jupyter Notebook 文件)和 `.py`(Python 脚本文件)
开发语言·python·jupyter
Jay-juice1 天前
QT信号与槽
开发语言·qt
fs哆哆1 天前
在VB.NET中,有没有 ?.这个运算符
java·开发语言·.net
驰羽1 天前
[GO]什么是热重载,如何使用Air工具
开发语言·后端·golang
傻啦嘿哟1 天前
Python爬取B站视频评论区情感分析:从数据采集到价值挖掘
开发语言·python
SirLancelot11 天前
MongoDB-基本介绍(一)基本概念、特点、适用场景、技术选型
java·数据库·分布式·后端·mongodb·软件工程·软件构建
AI算法董同学1 天前
轻松测试二维码生成与识别:使用Python的qrcode、opencv和pyzbar库
开发语言·python·opencv
陈增林1 天前
基于 PyQt5 的多算法视频关键帧提取工具
开发语言·qt·算法
程序员小凯1 天前
Spring Boot消息队列与事件驱动详解
java·spring boot·后端
郝学胜-神的一滴1 天前
Linux系统函数stat和lstat详解
linux·运维·服务器·开发语言·c++·程序人生·软件工程