Java值传递场景下,generateParenthesis的List为何被backtrack修改?
问题与解答
代码示例
public List<String> generateParenthesis(int n) { List<String> list = new ArrayList<String>(); backtrack(list, "", 0, 0, n); return list; } public void backtrack(List<String> list, String str, int open, int close, int max){ if(str.length() == max*2){ list.add(str); return; } if(open < max) backtrack(list, str+"(", open+1, close, max); if(close < open) backtrack(list, str+")", open, close+1, max); }
疑问
上述代码中,list是在generateParenthesis()方法中定义的字符串List。调用backtrack(list, "", 0, 0, n);时,并未接收backtrack()的返回值,但最终执行return list;时,list的状态却与backtrack()修改后的一致。
我的疑问是:generateParenthesis()中创建的list实例为何会被修改?它并非静态变量,且也没有通过list=backtrack(list, "", 0, 0, n);这类赋值操作接收返回值。
解答
这是因为Java中对象类型的参数是按引用传递的,具体逻辑如下:
- 在
generateParenthesis方法里创建的ArrayList实例会占据一块内存空间,list变量存储的是这个实例的内存地址。 - 调用
backtrack方法时,会把该内存地址传递给方法的list参数,此时原方法的list变量和参数list指向的是同一个内存中的ArrayList对象。 backtrack里执行list.add(str)是直接修改这个共享对象的内部数据(往列表中添加元素),并不是给参数list重新赋值。- 原方法的
list变量始终指向这个被修改的对象,所以最后return list时,自然能拿到修改后的状态,不需要额外的赋值操作。
内容的提问来源于stack exchange,提问作者Ankit Biswas
相关产品推荐
相关产品推荐

