Integer是不可变类,进入一个方法后,在里面的值的改变不会影响方法外的引用

本文通过一个Java小程序示例解释了为什么Java中的包装类如Integer是不可变的。通过内存图展示了当尝试修改这些包装类的值时,实际上是在创建一个新的对象而非修改原有对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看一个小程序


主函数的输出并没有像想像中一样会输出3,而是输出初始化的数值0

这是因为与String类似,所有的包装类都是final类,即不可变类。虽然在代码A处看起来是改变了counter的值,但实际上是创建了另一个对象,并将方法内的counter参数的引用指向了这个新创建的对象,由于是不同的引用,所以不会对方法外的引用有任何的影响。内存图如下所示:

在刚进入方法的时候:


执行counter = counter +1之后,由于Integer是不可变类,要改变它的值,其实是创建了一个新的对象,所以内存图如下:

<think>嗯,用户问的是Java方法参数传递中哪些类型是不可变的,哪些是可变的。首先,我需要回忆一下Java的参数传递机制。Java传递,对吧?不管是基本类型还是引用类型,传递的都是的副本。对于基本类型,比如int、char这些,传递的是实际的副本,所以修改副本不会影响,所以它们是不可变的。而对于对象引用,传递的是引用的副本,但副本和原引用指向同一个对象。这时候如果通过这个引用修改对象的属性,比如数组的元素或者对象的字段,那么原对象会被改变,所以这种情况下参数是可变的。但是如果让引用指向另一个对象,比如new一个新对象,原来的对象不会影响,这时候看起来不可变,但其实是因为引用本身是副本,而不是对象内容不可变。 比如,有一个方法参数是String,虽然String是不可变类,但传递的是引用的副本。如果在方法内部让这个引用指向另一个字符串,原引用不会变,但String本身的内容也不能被修改。所以对于对象类型来说,是否可变取决于对象本身是否允许修改内容,比如String不可变,而ArrayList这样的集合是可变的。 所以总结的话,基本类型参数是不可变的,因为传递的是副本。对象引用类型的参数,如果对象本身是可变的(比如数组、集合、自定义对象),那么通过引用修改对象内容会影响原对象,所以是可变参数。但如果对象是不可变的(如String、Integer),那么虽然引用传递的是副本,但对象内容无法修改,所以参数表现为不可变。 然后需要给出示例代码,比如基本类型在方法内修改不会影响,而修改对象的内容会影响原对象。例如,一个修改int和数组的例子,展示基本类型不变,数组内容变化的情况。 可能用户会混淆引用传递和传递,需要明确说明Java传递,引用类型的变量传递的是引用的副本,而不是对象本身。因此,对于可变对象,修改其内容会影响原对象,但重新赋值引用不会影响引用变量。 最后,相关的问题可能涉及参数传递机制,不可变类,如何保护对象不被修改,深拷贝与浅拷贝等。</think><< 在Java方法参数传递中,所有参数传递都是传递(传递的副本),但参数的可变性取决于参数类型本身的性质: ### 不可变的参数类型: 1. **基本数据类型**(如`int`、`double`、`char`等): 传递的是的副本,方法内修改不会影响原始变量。 ```java void modify(int x) { x = 10; // 修改的是副本,不影响原始 } ``` 2. **不可变对象**(如`String`、`Integer`等包装类): 虽然传递的是引用的副本,但这些类的实例本身不可修改(immutable),任何修改都会创建新对象。 ```java void modifyString(String s) { s = s.concat("!"); // 创建新对象,原始引用不变 } ``` ### 可变的参数类型: 1. **可变对象**(如数组、`ArrayList`、自定义对象): 传递的是引用的副本,但可以通过引用修改对象内部状态。 ```java void modifyArray(int[] arr) { arr[0] = 100; // 修改会影响原始数组 } void modifyList(ArrayList<String> list) { list.add("new"); // 修改会影响原始列表 } ``` ### 代码示例: ```java public class ParameterExample { public static void main(String[] args) { // 基本类型(不可变) int num = 5; modify(num); System.out.println(num); // 输出 5(改变) // 数组(可变) int[] array = {1, 2, 3}; modifyArray(array); System.out.println(array[0]); // 输出 100(已改变) // String(不可变) String s = "Hello"; modifyString(s); System.out.println(s); // 输出 Hello(改变) } static void modify(int x) { x = 10; } static void modifyArray(int[] arr) { arr[0] = 100; } static void modifyString(String s) { s = s.concat("!"); } } ``` ### 解释: - **基本类型**和**不可变对象**的副本在方法内部修改时,原始保持不变。 - **可变对象**的引用副本仍指向原始对象,因此方法内的修改会影响原始对象。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值