2013-07-09 19 views
0

这是我的第一篇文章。我最近开始对学习Java感兴趣,我已经阅读了一些初学者级别的教程,将http://docs.oracle.com保存为我的书签并阅读了几个示例代码。在方法中使用实例变量Linkedlist() - 为什么我必须在方法体中创建新的

现在搞乱了我自己的实践,我发现了一些奇怪的东西,在手册/教程/文档中我找不到任何令人满意的答案。

这是我制作的一个小类,用于练习IO和队列样式对象。它的意思是创建一个包含文件名和空链表的对象。然后它有一个方法来读取给定的文件,并将它们逐行添加到链表列表中。

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();} 
     } 

怪异的事情 - 当尝试使用类声明的类变量/实例变量队列(公共LinkedList的队列),一个还在构造开始时,方法里面,它编译罚款,但在运行时,它扔NPE在queue.add行。当我初始化方法变量队列里面的方法时,NPE消失了。为什么不能将方法添加到类变量队列中?它似乎使用fielhandle变量就好了! 同样如轮询方法所示,运行该类的代码(将其发布) - 它似乎实际上将行添加到实例变量队列中,而不仅仅是临时方法变量。 (这当然是好的,但我不知道如何和为什么) 到这里是我用来运行在手柄类的代码。

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);} 

     } 
    } 

所以任何人可以给我很好的解释,为什么我不能在运行时访问方法中的类变量队列,尽管我能够使用文件句柄变量。 接下来我应该做些什么? 任何人都可以告诉我类字段队列是如何填充的,尽管我在方法中声明了一个新的变量。或者handle.queue.poll以某种方式检测变量的形式方法?

回答

1

的问题是在这里:

Handle (File filename) { 
    filehandle=filename; 
    LinkedList<String> queue = new LinkedList<String>();  
} 

你不初始化实例字段queue,而您创建具有相同的名称,这是只适用于构造一个新的局部变量。将其更改为:

Handle (File filename) { 
    filehandle=filename; 
    queue = new LinkedList<String>();  
} 

它不应该抛出NPE。

1

在你的构造函数中,你声明了一个局部变量队列,隐藏你的类变量!

Handle (File filename) 
     { 
     filehandle=filename; 
     this.queue = new LinkedList<String>();  
     } 
+0

Aha so this.queue = new LinkedList ();或queue = new LinkedList ();在启动构造函数时应该创建新的队列,jet不会隐藏类变量。但正如我LinkedList queue = new LinkedList ();会宣布一个新的变量?因此,变量名前的类型声明是将它从初始化/填充新值等变为新变量声明的类型声明? –

+0

是的,就像这样:在你的示例代码中,你声明了一个局部变量(通过在类型声明前加上一个前缀),当构造函数完成时它会消失.BTW:你永远不要在你的类中声明实例变量为“public” ,让他们受到保护或私密 - 他们是你班级的内部人员,不应该从外面被肢解。 –

+0

从某种意义上说,我希望这个队列可以被外部类访问。长期规划就像这样 - 创建一个打开文件并开始逐行填充队列的类。现在其他类可以跳入其中,甚至可以在不同的线程中使用其中的许多类,并且开始从队列中“抽出”线路。如果不在这个班级内部公开排队,你会如何帮助完成这类任务?我们的想法是将其开发成一种“泵”类型的管道,它从文件中读取行并向下输送它们,后者管道和过滤器等部件则可以互换。 –

1

问题是您的LinkedList的可见性。它只在你的私有构造函数中可见。使用队列LinkedList只写这在构造函数:

queue = new LinkedList<String>(); 

还删除在addq

queue = new LinkedList<String>(); 
+0

Aha so this.queue = new LinkedList ();或queue = new LinkedList ();在启动构造函数时应该创建新的队列对象,jet不会隐藏类变量。\ n但是,因为我有LinkedList queue = new LinkedList ();会宣布一个新的变量?因此,变量名前的类型声明是将它从初始化/填充新值等变为新变量声明的类型声明? –

0

看起来没有地方射击NPE您的代码。 它会启动文件没有发现异常,如果提到文件不在位置。

你可以发布堆栈跟踪到更多的调查。

相关问题