Java递归方法中List参数为何无需返回值就能保留旧值?
问题解答:List递归参数为何能保留值?
原代码
public static void main (String[] args) { String str = "Test"; List<String> res = new ArrayList<String>(); pastValues(str, 0, "", res); //System.out.println("Ans:::"+res); } public static void pastValues(String str, int index, String curr, List<String> ans){ if(index == str.length()){ return; } pastValues(str, index + 1, curr + str.charAt(index), ans); System.out.println("Before:::"+ans); ans.add(curr + str.charAt(index)); System.out.println("After:::"+ans); }
输出结果
Before:::[] After:::[Test] Before:::[Test] After:::[Test, Tes] Before:::[Test, Tes] After:::[Test, Tes, Te] Before:::[Test, Tes, Te] After:::[Test, Tes, Te, T]
用户问题
我的问题是:List类型参数ans为何能保留原有值?根据我的认知,递归调用方法时会创建参数的新实例,方法返回后参数值会消失,除非返回该值,但本方法无返回值,那它为何还能保留旧值?请帮忙解答,谢谢。
解答
这是因为Java里引用类型的参数传递规则:
- 你在
main方法中创建的ArrayList实例存储在堆内存中,变量res保存的是指向该实例的引用(可理解为对象在堆中的地址)。 - 调用
pastValues方法时,传递给参数ans的是res引用的副本,而非新创建的ArrayList实例。所有递归调用中的ans变量,指向的都是同一个堆内存中的ArrayList对象。 - 无论递归调用多少次,对
ans调用add方法都是在操作同一个ArrayList实例,因此添加的元素会一直保留,不会随方法返回而消失。
你之前的认知误区在于混淆了值类型和引用类型的参数传递:值类型(如int、char)传递的是值的副本,修改副本不会影响原变量;而引用类型传递的是引用副本,操作的仍是原对象,所以修改会被保留。
内容的提问来源于stack exchange,提问作者Subrato Kumar Mahato
相关产品推荐
相关产品推荐

