为什么没有'else',它会在BTree的前序遍历中抛出java.lang.NullPointerException?

Why without 'else', it will throw java.lang.NullPointerException in preoder traversal of a BTree?

我是编程新手。我的问题可能很愚蠢。 (***如果对别人没有任何价值,后面我会删掉这个问题) 在这里查看这两个函数:

1.

StringBuilder sb  = new StringBuilder();
private String preorder(TreeNode root) {
        if(root == null){
          sb.append("null,");  
        } 
        sb.append(root.val);
        sb.append(",");
        String l = preorder(root.left);
        String r = preorder(root.right);

        return sb.toString();
    }

2.

 StringBuilder sb  = new StringBuilder();
 private String preorder(TreeNode root) {
        if(root == null){
          sb.append("null,");  
        }
        else{
            sb.append(root.val);
            sb.append(",");
            String l = preorder(root.left);
            String r = preorder(root.right);
        }
        return sb.toString();
    }

如果我在main函数中调用这两个函数。 第一个会扔

java.lang.NullPointerException error. 

我理解当 java.lang.NullPointerException 发生时:

  • 1。当声明一个变量但没有创建一个对象时
  • 2。在尝试使用变量的内容之前分配给变量

    (这部分更新: IF条件后,不管有没有else,都会执行剩下的body,感谢大家的帮助)

    (陈旧。忽略其余部分:)

    之后
    if(root == null) 
    

    剩下的应该是

    root != null
    

    如果我错了请纠正我。

  • 回答

    您缺少一个 else 案例。

    private String preorder(TreeNode root) {
        if(root == null){
          sb.append("null,");  
        }else{ 
        // ... 
        }
    

    如果您不添加 else,则 if 条件 下方的代码仍将执行 return

    它会抛出一个 NPE 因为在你的条件之后你 尝试使用

    访问 root

    sb.append(root.val);

    进一步说明

    你需要像句子一样读。

    if(thisIsTrue){
      // Then do that
    }else{
      // Do that
    }
    

    其中 "thisIsTrue" 是您的状况。即 root != null.

    如果您尝试使用 root.val 访问 root 的成员, 如果您尝试访问 val,那么根 不能为空 , 否则将抛出 NullPointerException

    打个比方..想象你有一袋苹果。 你想做的是抓住一个苹果,但你没有袋子。

    我想这很清楚。

    如果省略 else 子句,则执行如下:

    if(thisIsTrue){
      // It will do that, if condition is true
    }
    
    // It will ALWAYS execute this, even if condition is false
    
    1. 和if/else 你开了两个分店。其中只有一个被执行。

    2. 有if,没有else 你有一个条件分支,如果 条件为真,但下面的代码将执行 always afterwards.