对象在debug模式下不为null,被方法调用时为null?

The object is not null when it is in debug mode, but is null when it is called by a method?

当我 运行 我的 TreeNode 代码时,编译器说 countUnivalSubtrees 方法调用的 TreeNode 为空。但是,当我 运行 调试模式时,它告诉我我创建的 Treenode 不为空。 class Treenode 的对象foolbar 有它的根、左分支和右分支。那么为什么在调用foolbar时,该方法接收到一个空对象?

1.The 树节点代码

package lc_250;


public class TreeNode {
    int val;
    TreeNode root;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
    public void put(int val){
        this.root =  put(this.root, val);
    }
    private TreeNode put(TreeNode node_now, int val){
        if (node_now == null) return new TreeNode(val);
        else if (val < node_now.val) node_now.left = put(node_now.left, val);
        else if (val > node_now.val) node_now.right = put(node_now.right, val);
        else node_now.val = val;
        return node_now;
    }

    public static void main(String[] args) {
        TreeNode foolbar = new TreeNode(3);
        foolbar.put(5);
        foolbar.put(6);
        foolbar.put(3);
        foolbar.put(2);
        foolbar.put(4);
        foolbar.put(9);
        foolbar.put(8);
        foolbar.put(7);
        cson250 foolclass = new cson250();
        int num = foolclass.countUnivalSubtrees(foolbar);
    }
}
  1. cson250码
package lc_250;
public class cson250 {
    public  int num = 0;
    public  int countUnivalSubtrees(TreeNode root) {
        count(root);
        return num;
    }

    public boolean count(TreeNode root){
        if (root == null) System.out.println("bro Treenode is null");
        boolean left = count(root.left);
        boolean right = count(root.right);

       if ( root.left == null && root.right == null){
           num++;
           return true;
       }

       if (left&&right){
           if (root.left!=null && root.left.val != root.val){
               return false;
           }
           if (root.right!= null && root.right.val != root.val){
               return false;
           }
           num++;
           return true;
       }
       return false;
    }

}

我建议,如果你想在调试模式下看到你的树节点为空,让你的代码看起来像这样,以便在 root == null 时放置调试点。

public boolean count(TreeNode root){
    if (root == null) 
        System.out.println("bro Treenode is null");

这样您将在程序流的某个时刻看到您的根为空。 您可以在打印的行放置一个调试点 System.out.println("bro Treenode is null");

您在调试器中显示了与 NPE 发生位置不同的位置。这就是为什么您的监视字段不显示 root == null.

的原因

在你的树的每个叶子中,root 将是 null,所以当你遇到第一个叶子时(应该是值为“2”的节点,因为这是最小值在你的列表中,你把较小的值放在左边的节点上,你首先在你的 count 方法中检查左边的节点),你将首先执行

if (root == null) System.out.println("bro Treenode is null");

但随后您的代码继续执行

boolean left = count(root.left);

然后出现 NullPointerException,因为 root 当然仍然是 null,因此您无法访问 root.left

所有防止递归调用的检查都发生在调用之后,因此它们并不能真正帮助停止访问 root,即 null