【问题标题】:null pointer exception in stack implementation堆栈实现中的空指针异常
【发布时间】:2014-12-18 00:56:14
【问题描述】:

这段代码如何在 push 和 main 中产生 NullPointerException: 代码如下:

class Stack {
  private char ch[];
  private int top;

  Stack(int n) {
    char ch[] = new char[n];
    top = -1;
  }

  void push(char c) {
    if (top == ch.length - 1) {
      System.out.println("Stack full.");
      return;
    }
    top++;
    ch[top] = c;
  }

  char pop() {
    if (isEmpty()) {
      System.out.println("Stack empty");
      return (char) 0;
    }
    char p;
    p = ch[top];
    top--;
    return p;
  }

  boolean isEmpty() {
    if (top == -1)
      return true;
    else
      return false;
  }
}


class StackDemo {
  public static void main(String args[]) {
    final int size = 10;
    Stack s = new Stack(size);

    // Push charecters into the stack
    for (int i = 0; i < size; i++) {
      s.push((char) ((int) 'A' + i));
    }
    // pop the stack untill its empty
    for (int i = size - 1; i >= 0; i--) {
      System.out.println("Poped element " + i + " is " + s.pop());
    }
  }
}

生成的错误码是:

0StackDemo.main(StackDemo.java:46) 的 Stack.push(StackDemo.java:11) 的线程“main”java.lang.NullPointerException 中的异常

我是否必须将这些类放在一个包中,因为 java 中已经有一个 Stack 库?

【问题讨论】:

    标签: java nullpointerexception stack runtime-error


    【解决方案1】:

    你声明了两次 char ch[]!一个是全局的,另一个是构造函数内的本地!在构造函数中你必须有:

    Stack(int n) {
       ch = new char[n];
       top = -1;
     }
    

    【讨论】:

      【解决方案2】:

      问题出在这里:

      char ch[] = new char[n];
      

      您在构造函数中本地声明数组,因此该字段永远不会被分配。通过这样做来修复它:

      this.ch = new char[n];
      

      this 关键字当然是可选的,但它可以让您更清楚地了解您在做什么,并且您的代码更具可读性。


      NullPointerException 通常发生在您在 null 上调用 . 时。例如,此代码将抛出 NPE:

      Object o = null;
      o.toString();
      

      您的代码抛出了NullPointerException,因为您从未分配过ch 变量。您的赋值语句是在本地范围中分配变量。

      • 本地范围 - 仅适用于您当前的 { } 块的范围,例如 构造函数声明方法声明
      • 全局范围 - 适用于当前 { } 块之外的范围,例如字段分配。

      因为char ch[] = new char[n]; 是一个本地范围 分配,您的全局范围 private char ch[]; 从未被分配,因此具有null 的默认值。

      【讨论】:

      • 感谢您的帮助....但是您能更清楚地解释为什么它会生成空指针异常吗?
      • @m.souvik 这将解决您的一个问题,但是如果您查看我上面的答案,您会发现您还有另一个问题。看看吧。
      【解决方案3】:

      一个问题是您在全局和构造函数中声明了两次 ch。你不应该在你的构造函数中声明。

      Stack(int n) {
          char ch[] = new char[n];
          top = -1;
      }
      

      到:

      Stack(int n) {
          this.ch = new char[n];
          top = -1;
      }
      

      isEmpty() 应该是 -1,而不是 0:

      boolean isEmpty() {
              if (top == 0)
                return true;
              else
                return false;
      }
      

      isEmpty() 方法应该是:

      boolean isEmpty() {
          if (top == -1)
            return true;
          else
            return false;
      }
      

      另一个问题是当你在构造函数中初始化对象时你设置了top = -1。在您的 pop 方法中,您检查 isEmpty() 如果 top == 0 则返回 true。问题是它在初始化时为空,但 top == -1。因此,如果在对象初始化后立即调用 pop() 将引发 IndexOutOfBounds 异常,因为您正在尝试访问 ch[top] 或 ch[-1]。

      您收到 NullPointerException 的原因是因为您的全局变量 ch 在创建对象时被初始化为 null。在您的构造函数中,您应该从 null 更改为大小为 n 的新数组,但您要创建一个本地数组 ch 而不是初始化您在其他方法中使用的全局数组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-05
        • 1970-01-01
        • 1970-01-01
        • 2018-02-14
        • 2013-04-28
        • 2021-12-09
        • 1970-01-01
        相关资源
        最近更新 更多