2

我正在编写一个程序,它将一系列单词分成标记并读取文本,然后计算它们的频率。此代码有几个相关代码(WordCount、FreqStudy 和 Echo),但 WordFreq 类是导致 java.lang.NullPointerException 错误的原因。这是我的 WordFreq 代码:

import java.util.*;
import java.io.*;

public class WordFreq extends Echo{

  WordCount[] wcArray;
  int ct;
  String[] sentence;
  double freq;
  String newLine;

  public WordFreq(String f, String words) throws IOException{
    super(f);
    String[] wordString = words.split(" ");
    for(int i=0; i<wordString.length; i++)
      wcArray[i] = new WordCount(wordString[i]);
    Scanner scan = new Scanner(new FileReader(fileName));
  }

  public void processLine(String line){
    newLine = line.toLowerCase();
    sentence = newLine.split(" "); 
    for(String s: sentence){
      for(WordCount w: wcArray){
        if(w.getWord().equals(s))
          w.incCount();
      }
      ct++;
    }     
  }

  public void reportFrequencies(){
    for (int i=0; i<wcArray.length; i++){
      freq = (wcArray[i].getCount() / ct); 
      System.out.print(wcArray[i].getWord()+" ");
      System.out.printf("%6.4f\n", freq);
    }
  }
}

当我给它一个文件以通过 FreqStudy 主类读取时,我收到的错误如下所示:

java.lang.NullPointerException
    at WordFreq.<init>(WordFreq.java:17)
    at FreqStudy.main(FreqStudy.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)

我真的不明白问题是什么,我整天都在研究这个,所以我觉得脑死了。如果可以的话,请看一下,我将不胜感激。

编辑:我意识到我没有在发布后立即初始化它,但我的频率返回 0 结果。有人帮忙吗?

4

2 回答 2

6

wcArray在分配任何值之前初始化数组:

wcArray = new WordCount[wordString.length];
于 2013-04-16T23:24:08.980 回答
4

您需要仔细检查堆栈跟踪:

java.lang.NullPointerException
    at WordFreq.<init>(WordFreq.java:17)

在 WordFreq ( WordFreq.java:17) 的第 17 行附近,它位于 WordFreq 类 ( WordFreq.<init>) 的构造函数中,当它是null.

wcArray[i] = new WordCount(wordString[i]);

可能的候选人:wcArraywordString。现在确保这些对象/数组已初始化。wordString通过 的返回值做了split(),但wcArray没有。数组需要分配(wcArray)或分配给预先存在的数组(wordString):

String[] wordString = words.split(" ");
wcArray = new String[wordString.length]
for(int i=0; i<wordString.length; i++)
  wcArray[i] = new WordCount(wordString[i]);

进一步的考虑:人们可能认为它wcArray[i]可能为 null 并导致 NPE,但由于它是赋值的目标,它不会导致 NPE - 该null值将被传入的赋值覆盖。

类似地,可能会认为wordString[i]可能为 null 并导致 NPE,但这会导致 anull被传递给方法,这很好。如果 WordCount 构造函数在传递给它时遇到问题null,则堆栈跟踪将在WordCount条目上方包含一个at WordFreq.<init>条目。

于 2013-04-16T23:39:14.573 回答