前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >写了那么多年代码,还犯这么低级的错误!

写了那么多年代码,还犯这么低级的错误!

作者头像
xiaoyi
发布2024-04-10 16:01:04
710
发布2024-04-10 16:01:04
举报
文章被收录于专栏:小义思小义思

场景是这样的,有个局部变量a,传给方法A然后在A方法里面赋值,接着又传给方法B,在方法B里面取值。也就是业务需求希望通过A改变a的值来控制B的执行逻辑。这就要涉及到JAVA中参数的值传递和引用传递。先用基本类型boolean来实现一下,代码如下:

代码语言:javascript
复制
public class ComTest {
    
    @Test
    public void testT() {
        boolean a = false;
        funA(a);
        funB(a);
    }

    public void funA(boolean a) {
        a = true;
    }

    public void funB(boolean a) {
        if (a) {
            System.out.println("change success");
        } else {
            System.out.println("nothing happen");
        }
    }
}

结果打印的是nothing happen,a值没有被修改,这是因为基本数据类型(如int、float、double等)是通过值传递的,在执行过程中程序将变量a的值复制一份传递给了方法A和方法B,而不是传递变量本身。

既然基本数据类型不行,换成封装类型Boolean试试。

代码语言:javascript
复制
public class ComTest {
    
    @Test
    public void testT() {
        Boolean a = false;
        funA(a);
        funB(a);
    }

    public void funA(Boolean a) {
        a = true;
    }

    public void funB(Boolean a) {
        if (a) {
            System.out.println("change success");
        } else {
            System.out.println("nothing happen");
        }
    }
}

结果还是nothing happen,这是乍回事?那换成字符串再看看。

代码语言:javascript
复制
public class ComTest {

    @Test
    public void testT() {
        String a = "0";
        funA(a);
        funB(a);
    }

    public void funA(String a) {
        a = "1";
    }

    public void funB(String a) {
        if ("1".equals(a)) {
            System.out.println("change success");
        } else {
            System.out.println("nothing happen");
        }
    }
}

打印结果还是没变化,虽然已经不用基本类型,但还是赋值不成功,这是因为在Java中,对于不可变对象(如Boolean、String等),每次对其进行修改时都会创建一个新的对象来代替新的值,原始的对象保持不变,不受修改的影响,从而提供更好的线程安全性。

注意,在Java中,以下对象是不可变的。

代码语言:javascript
复制
1、String类的对象。一旦创建了一个String对象,它的值就不能被改变。
2、BigInteger和BigDecimal类的对象。这两个类提供了不可变的数值对象。
3、基本数据类型(byte, short, int, long, float, double, boolean)的封装类型(例如Byte, Short, Integer, Long, Float, Double, Boolean)都是不可变的。
4、枚举类型(enum)。
5、一些java集合类的部分实现,比如Arrays.asList()返回的列表,Collections.unmodifiableList()返回的列表等。
6、java.lang.Object类中的final字段,如果一个字段被声明为final,那么这个字段的值就不能被修改。
7、java.lang.Math类中的所有静态字段,如PI和E等。
8、java.lang.Runtime类中的freeMemory()和totalMemory()方法返回的值也是不可变的。

既然以上方法的都不满足,只好使用对象的引用传递了,重新定义一个新的对象,对对象内的属性赋值,然后再在方法中传递。

代码语言:javascript
复制
public class ComTest {

    @Test
    public void testT() {
        Flag flag = new Flag();
        funA(flag);
        funB(flag);
    }

    public void funA(Flag a) {
        a.setA(true);
    }

    public void funB(Flag a) {
        if (a.isA()) {
            System.out.println("change success");
        } else {
            System.out.println("nothing happen");
        }
    }

    @Data
    class Flag {
        boolean a = false;
    }
}
//打印结果
//change success

引用传递与值传递不同,它实际上是将实际参数的内存地址传递给方法。因此,在方法内部对参数进行修改会影响到实际参数的值,所以可以实现方法间变量的传递。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-01-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员小义 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档