You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 03:16:07