堆栈实现中的空指针异常

时间:2014-10-22 14:22:11

标签: java nullpointerexception stack runtime-error

这段代码如何在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());
    }
  }
}

生成的错误代码是:

  
    

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

  

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

3 个答案:

答案 0 :(得分:4)

问题在于:

char ch[] = new char[n];

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

this.ch = new char[n];

关键字this当然是可选的,但它可以让您更清楚自己所做的事情以及您的代码的可读性。


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

Object o = null;
o.toString();

您的代码抛出NullPointerException因为您从未分配过ch变量。您的作业声明是在本地作用域中分配变量。

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

由于char ch[] = new char[n];本地范围分配,您的全局范围 private char ch[];从未分配,因此默认值为{{ 1}}。

答案 1 :(得分:2)

你宣布了两次char ch []!一个作为全局,另一个作为构造函数内的局部!在构造函数中,您必须具有:

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

答案 2 :(得分:2)

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

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

为:

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

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

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。问题是它在初始化时是空的但顶部== -1。因此,如果在初始化对象后立即调用,pop()将抛出一个IndexOutOfBounds异常,因为您试图访问ch [top]或ch [-1]。

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