这是我在这里的第一篇文章。我最近开始对学习Java感兴趣,我阅读了一些初级教程http://docs.oracle.com作为我的书签,并阅读了几个示例代码。
现在,我在自己的练习中发现了一些奇怪的事情,我在手册/教程/文档中找不到任何令人满意的答案。
我制作了一个小类来练习IO和队列样式的对象。它旨在创建一个包含文件名和空链表的对象。然后,它有一个方法来读取给定的文件,并将其中的行逐个添加到linkedlist队列中。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.LinkedList;
public class Handle
{
public File filehandle;
public LinkedList<String> queue;
Handle (File filename)
{
filehandle=filename;
LinkedList<String> queue = new LinkedList<String>();
}
public void addq()
{
try{
FileReader ava;
ava = new FileReader(filehandle);
//without initializing new linekedlist queue it'll give NPE in queue.add
//why can't it use class/instance variable queue it does fine with filehandle
queue = new LinkedList<String>();
BufferedReader br = null;
String sCurrentLine;
br = new BufferedReader(ava);
while ((sCurrentLine = br.readLine()) != null)
{
queue.add(sCurrentLine);
}
queue.offer("POISON");
}
catch (IOException e) {e.printStackTrace();}
}
奇怪的是,当试图使用类中声明的类变量/实例变量队列(public LinkedList队列)时,该队列也在构造函数中启动,在方法内部,它编译得很好,但在运行时,它在queue.add行中抛出了NPE。当我初始化方法内部的方法变量队列时,NPE消失了。为什么该方法不能添加到类变量队列中?它似乎很好地使用了fielhandle变量!同样,正如poll方法导致代码运行类(将其发布)所示,它似乎仍然实际将行添加到实例变量队列中,而不仅仅是临时方法变量。(这当然很好,但我不明白如何以及为什么)下面是我用来在中运行Handle类的代码
import java.io.File;
import java.util.LinkedList;
class Runner
{
public static void main(String[] args)
{
File file = new File("proovidest.csv");
Handle handle =new Handle(file);
//using the constructor, now we have object with filehandle and empty queue variables
handle.addq();
String mison;
//so apparently the instance variable queue is still filled with lines (good)
//but how? the method had to delcare its own variable (why), but still the class field is //now filled? how?
while ((mison = handle.queue.poll()) != "POISON")
{System.out.println(mison);}
}
}
所以,有人能很好地解释为什么我不能在运行时访问方法中的类变量队列,尽管我可以使用filehandle变量。那么我该怎么访问它呢?有人能告诉我,尽管我在方法中声明了一个新变量,但类字段队列是如何被填充的吗。或者handle.queue.poll是否以某种方式检测方法中的变量?
问题就在这里:
Handle (File filename) {
filehandle=filename;
LinkedList<String> queue = new LinkedList<String>();
}
您不初始化实例字段queue
,而是创建一个具有相同名称的新局部变量,该名称仅在构造函数中有效。更改为:
Handle (File filename) {
filehandle=filename;
queue = new LinkedList<String>();
}
它不应该抛出NPE。
在构造函数中,您声明了一个局部变量队列,隐藏了类变量!
Handle (File filename)
{
filehandle=filename;
this.queue = new LinkedList<String>();
}
问题在于LinkedList
的可见性。它只在您的私有构造函数中可见。要使用队列LinkedList
,只需在构造函数中写入以下内容:
queue = new LinkedList<String>();
进一步去除addq
:中的
queue = new LinkedList<String>();
看起来没有地方在代码中激发NPE。如果提到文件不在位置,它将触发"未找到文件"异常。
你能将堆栈跟踪发布到更多的调查中吗。