【问题标题】:Null Pointer Exception when Creating Object [duplicate]创建对象时出现空指针异常[重复]
【发布时间】:2014-06-03 17:03:10
【问题描述】:

我想知道是否有人可以帮助我找出这个空指针异常。我正在制作一个程序来查找英语单词的所有字谜。我创建了一个类EnglishDictionary,当给定一个英语单词的长度及其第一个字母时,它会扫描一个包含所有英语单词的文本文件,然后选择将长度相同且包含第一个字母的单词添加到ArrayList。代码如下:

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;

public class EnglishDictionary {

    public EnglishDictionary(String firstLetter, int wordLength) {
        ArrayList<String> words = new ArrayList<String>();
        processDict(firstLetter, wordLength);
    }

    public void processDict(String firstLetter, int wordLength) {
        try {
            FileReader fReader = new FileReader("englishWords.txt");
            BufferedReader reader = new BufferedReader(fReader);
            while (true) {
                String line = reader.readLine();
                if (line == null) {
                    break;
                } else {
                    if (line.length() == wordLength) {
                        words.add(line);
                    }
                }
            }
        } catch (IOException e) {
            System.out.println("File does not exist.");
        }
    }

    public ArrayList<String> getWords() {
        return words;
    }

    public void printWords() {
        for (String word : words) {
            System.out.println(word);
        }
    }

    private ArrayList<String> words;

}

如您所见,我还没有添加检查第一个字母是否在所选英文单词中的功能。当我从另一个类创建 EnglishDictionary 对象时,我得到一个空指针异常。它说:

Exception in thread "main" java.lang.NullPointerException
    at EnglishDictionary.processDict(EnglishDictionary.java:23)
    at EnglishDictionary.<init>(EnglishDictionary.java:10)
    at Main.main(Main.java:6)

我似乎无法弄清楚这是从哪里来的。其他人能看到吗?提前致谢。

【问题讨论】:

  • 一个好的答案不值得任何投票。这几天发生了什么。

标签: java nullpointerexception


【解决方案1】:

words 未正确初始化。您正在初始化一个 LOCAL 变量词,它隐藏了 CLASS 变量词。

在您的构造函数中执行此操作:

public EnglishDictionary(String firstLetter, int wordLength) {
  //ArrayList<String> words = new ArrayList<String>();  // Creates a local variable called 'words'; class member does NOT get initialized.
  words = new ArrayList<String>(); // THIS initializes the class variable.
  processDict(firstLetter, wordLength);

}

【讨论】:

  • 我已经在 4 分钟前回答了同样的问题。 :) 不是吗?
  • 您的回答并没有说明问题在于局部变量隐藏了类成员。
  • 我认为你采取了错误的方式。这是OP错误地做的。 OP 并没有尝试在不使用任何地方的情况下创建局部变量。下次您投反对票时,请务必尝试发表评论。我已经详细解释过了。
  • 是的,这显然是一个错误,但这是一个微妙且难以察觉的错误。恕我直言,有人很容易查看代码并认为变量已初始化而没有意识到存在范围问题。
  • 你了解实例变量吗?如果是,那么 OP 也理解相同的术语。我也使用内联 cmets 突出显示了确切的行号。
【解决方案2】:

解决方案 1

应该是这样的。实例变量words 未初始化。

public EnglishDictionary(String firstLetter, int wordLength) {
    words = new ArrayList<String>();           // THIS LINE IS CHANGED
    processDict(firstLetter, wordLength);
}

解决方案 2

在声明实例成员时初始化以避免NullPointerException

private ArrayList<String> words = new ArrayList<String>();

public EnglishDictionary(String firstLetter, int wordLength) {
    //ArrayList<String> words = new ArrayList<String>();    //REMOVE THIS LINE
    processDict(firstLetter, wordLength);
}

解决方案 3

为了更安全,请使用 final 来避免此类在编译时发现的问题。

private final ArrayList<String> words; 

问题出在words.add(line);,因为words根本没有初始化。

【讨论】:

  • 反对者永远不要忘记发表评论。
【解决方案3】:

问题是范围问题。

你的方法:

public EnglishDictionary(String firstLetter, int wordLength) {
    ArrayList<String> words = new ArrayList<String>();
    processDict(firstLetter, wordLength);
}

实例化 ArrayList 单词,但是单词的范围仅对此方法可见。因此,当以另一种方法调用单词时,您会收到错误。

您可以通过将 Arraylist 单词移到方法之外来解决此问题,并在您的方法中将其实例化:

ArrayList<String> words;


public EnglishDictionary(String firstLetter, int wordLength) {
    words = new ArrayList<String>();
    processDict(firstLetter, wordLength);
}

【讨论】:

  • 看OP问题的最后一行。
【解决方案4】:

在构造函数中将 ArrayList&lt;String&gt; words = new ArrayList&lt;String&gt;(); 更改为 words = new ArrayList&lt;String&gt;();

在第一种情况下,您正在创建一个名为“word”的本地数组列表,其范围仅适用于构造函数。但是你实际上需要初始化实例变量'word'

【讨论】:

    猜你喜欢
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多