54. Java 类和对象 - 传递引用数据类型参数

54. Java 类和对象 - 传递引用数据类型参数

在 Java 中,引用类型(如对象或数组)作为参数传递时,采用的也是**值传递(pass-by-value)**机制!不过这里要特别注意的是:

  1. 引用的复制:传递的是对象的引用副本,而不是对象本身。
  2. 影响对象状态:如果你通过引用修改对象的属性(字段),这些更改会影响原对象,因为引用指向的是同一个对象。
  3. 重新赋值引用:如果你在方法里让引用指向另一个对象,这种改变不会影响外部的引用。

🌟 1. 示例:moveCircle 方法

来看个例子:

public void moveCircle(Circle circle, int deltaX, int deltaY) {
    // ✅ 改变 circle 引用指向对象的状态
    circle.setX(circle.getX() + deltaX);
    circle.setY(circle.getY() + deltaY);

    // 🚨 将 circle 引用重新指向一个新的 Circle 对象
    circle = new Circle(0, 0);
}

🎯 1.1 改变对象属性

circle.setX(circle.getX() + deltaX);
circle.setY(circle.getY() + deltaY);
  • circle 是引用的副本:它指向同一个 Circle 对象。
  • 更改对象的状态:通过 setX()setY() 修改的是对象本身的字段,因此这些更改在方法外部依然生效。

🚨 1.2 重新赋值引用

circle = new Circle(0, 0);
  • 这行代码让 circle 重新指向 一个新对象 (0, 0)
  • 影响范围:只在当前方法内部生效!外部的 myCircle 不会受影响,因为它指向的还是最初的对象。

📞 2. 调用方法示例

Circle myCircle = new Circle(10, 15);  // 初始坐标 (10, 15)
moveCircle(myCircle, 23, 56);
System.out.println("After moveCircle: x = " + myCircle.getX() + ", y = " + myCircle.getY());

执行逻辑:

  1. 初始状态myCircle.x = 10myCircle.y = 15
  2. 调用 moveCircle(myCircle, 23, 56) 后:
    • 坐标更新myCircle.x = 10 + 23 = 33
    • 坐标更新myCircle.y = 15 + 56 = 71
    • 🚨 引用重新赋值:方法内部的 circle 指向新对象 (0, 0),但这不会影响外部的 myCircle
  3. 方法结束myCircle 仍指向原对象 (33, 71)

输出结果:

After moveCircle: x = 33, y = 71

🏁 3. 理解机制:值传递 vs. 引用的可变性

Java 的引用类型参数机制可以这样理解:

  • 值传递:无论基元类型还是引用类型,Java 传递的都是值。引用类型传递的是对象引用的副本。
  • 对象可变性:通过引用修改对象的字段会影响外部对象,因为两者指向的是同一个内存地址。
  • 重新赋值引用:仅在方法内部生效,不会影响方法外的引用。

📚 4. 小结

🌟 一句话记忆:Java 总是值传递!

  • 基元类型:传递的是值本身。
  • 引用类型:传递的是引用的值(对象地址的副本)。
  • ✅ 修改对象字段 = 影响原对象
  • 🚨 重新赋值引用 = 只影响方法内的副本,不改变外部引用

理解这点,能够帮你避免在方法中误以为重新赋值引用就会改变外部对象的问题,也让你在编写代码时更清晰地掌握对象和引用的关系。💡

🎯 思考题

你觉得下面这段代码输出的是什么?为什么?

public class Test {
    public static void main(String[] args) {
        String s = "Hello";
        changeString(s);
        System.out.println(s);
    }

    public static void changeString(String str) {
        str = "World";
    }
}

👉 答案可以在下节课揭晓,也欢迎大家讨论你的理解!🔥


🎯 思考题解析

在 Java 中,字符串 (String) 是 不可变对象(Immutable)。当你在 changeString 方法中执行 str = "World";,实际上是让 str 指向了一个新的字符串对象,但这不会影响 main 方法中原来的 s 变量。

🚀 关键点:

  1. String 在 Java 中是 不可变的,任何修改都会生成一个新的 String 对象,而不会影响原来的对象。
  2. Java 方法传递的是参数的副本,这里传递的是 s 的引用的副本,而 str = "World"; 只是改变了 str 的指向,并未修改 s 指向的内容。

🔍 输出结果:

Hello

👉 思考延伸:
如果想要修改 String 的内容,该怎么办?有什么数据类型是可变的?欢迎大家讨论!🔥


👉 思考延伸解析:

在 Java 中,String不可变(Immutable) 的,所以无法直接修改它的内容。那么如果我们想要修改字符串,该怎么办呢?

解决方案 1:使用 StringBuilderStringBuffer(可变字符串)

StringBuilderStringBuffer 提供了 可变字符串,允许我们在原有字符串上进行修改,而不会创建新的对象。

🔹 示例代码:

java复制编辑public class Test {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello");
        changeString(sb);
        System.out.println(sb);
    }

    public static void changeString(StringBuilder str) {
        str.append(" World");
    }
}

🔹 输出结果:

Hello World

🎯 为什么这样就能修改呢?
因为 StringBuilder可变对象str.append(" World") 修改了同一个对象的内容,所以 main 方法中的 sb 也受到了影响。


解决方案 2:用 String 手动返回新值

如果仍想用 String,可以返回修改后的新值

🔹 示例代码:

public class Test {
    public static void main(String[] args) {
        String s = "Hello";
        s = changeString(s);
        System.out.println(s);
    }

    public static String changeString(String str) {
        return str + " World";
    }
}

🔹 输出结果:

Hello World

🎯 为什么这样可以?
因为 String 是不可变的,所以我们需要手动接收返回的新字符串,否则原来的 s 不会改变。


🔥 总结:

如果想要修改字符串的内容: 1️⃣ 使用 StringBuilder / StringBuffer(推荐) —— 适用于频繁修改字符串的场景,避免创建大量 String 对象,提升性能。
2️⃣ String 返回新值 —— 适用于方法内部修改字符串后,返回新字符串给调用者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yaoxin521123

谢谢您的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值