java - 为什么 List<List<Integer>> 会更新,即使它不是全局变量?

标签 java methods global-variables

allpaths 是一个在 findPaths(...) 方法中定义的 List>,它在其范围内调用 dfs(...) 方法,但我不明白为什么 allpaths 会更新,因为它不是全局变量?那么,调用 dfs 方法后 allpaths List 是如何更新的呢?

import java.util.*;

class TreeNode {
  int val;
  TreeNode left;
  TreeNode right;

  TreeNode(int x) {
    val = x;
  }
};

class FindAllTreePaths {
  public static List<List<Integer>> findPaths(TreeNode root, int sum) {
    List<List<Integer>> allpaths = new ArrayList<List<Integer>>();
    List<Integer> cpath = new ArrayList<Integer>();
    dfs(root, sum, cpath, allpaths);
    return allpaths;
  }
  private static void dfs(TreeNode root, int sum, List<Integer> cpath, List<List<Integer>> result){
    if(root == null){
      return;
    }
    if(root.val == sum && root.left == null && root.right == null){
      cpath.add(root.val);
      result.add(cpath);
    }
    List<Integer> temp = new ArrayList<Integer>();
    temp.addAll(cpath);
    temp.add(root.val);
    dfs(root.left, sum-root.val, temp, result);
    dfs(root.right, sum-root.val, temp, result);
  }

  public static void main(String[] args) {
    TreeNode root = new TreeNode(12);
    root.left = new TreeNode(7);
    root.right = new TreeNode(1);
    root.left.left = new TreeNode(4);
    root.right.left = new TreeNode(10);
    root.right.right = new TreeNode(5);
    int sum = 18;
    List<List<Integer>> result = FindAllTreePaths.findPaths(root, sum);
    System.out.println("Tree paths with sum " + sum + ": " + result);
  }
}

此外,我尝试了以下代码,它是上述场景的缩放版本:

public class Main {
    public static void main(String[] args) {
        int c = call();
        System.out.println(c);
    }

    public static int call(){
        int c=100;
        call1(c);
        return c;
    }

    private static void call1(int d){
        c=4;
        d = 4;
    }
}

结果是: c=100

这表明 c 对于 call1() 来说不是全局的。

编辑: 我尝试了以下代码,因为我被告知引用类型变量遵循引用传递,但事实并非如此:

public class Main {
    public static void main(String[] args) {
        call();
    }

    public static void call(){
        String c="Jack";
        List<Integer> l = new ArrayList<Integer>();
        l.add(1);
        call1(c, l);
        System.out.println(c);
        System.out.println(l.get(0) + " " + l.get(1));
    }

    private static void call1(String c, List<Integer> l){
        l.add(2);
        c="Jack Ryan";
    }
}

但是输出是: jack 1 2

这意味着 String 是按值传递的,而 List 是按引用传递的。

最佳答案

嗯,这就是所有原始数据类型(int、double、...)和引用之间的区别。 创建变量时,每次将此变量传递给另一个方法时,都会复制它的值。原始数据类型和引用之间的区别在于它们存储哪些值。

原始数据类型

直接存储值(例如数字)。当您传递变量时,数字将被复制。

引用文献

当你处理对象时,你实际上处理的是对对象的引用。存储对象的变量实际上存储对该对象的引用(如地址)。当您将此变量传递给另一个方法时,仅复制该对象的地址,这意味着这两个方法在内存中使用完全相同的对象。

这就是为什么您使用整数的示例按预期工作。如果您想实际克隆一个对象,您必须实现 Cloneable (java.lang.Cloneable) 接口(interface)。

关于java - 为什么 List<List<Integer>> 会更新,即使它不是全局变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57444175/

相关文章:

java - 应用内结算 mPurchaseFinishedListener 错误

javascript - 在 JavaScript 函数中使用全局变量

Android 选项卡和全局变量

python - 动态全局变量赋值

ruby - 定义方法参数的条件

c++ - 为什么在没有参数的方法中使用const?

java - 如果同步块(synchronized block)中的锁对象发生更改,会发生什么情况

java - 即使使用关键字 "after",AOP 方面也会在给定方法之前执行?

Java Webservice 在使用之前请求用户名和密码

java - SpringMVC 如何在调用构造函数时从 session 范围获取 bean