Java 简单的记录器类,但是否引发空指针异常?

Java 简单的记录器类,但是否引发空指针异常?,java,Java,我已经编写了一个简单的logger类,可以作为一个实例,它允许我将信息写入一个文件。前一段时间它在一个示例中工作,但现在抛出了一个空指针异常错误。我真的不知道为什么会这样。我已经把课程代码放在下面了 类别代码: import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter;

我已经编写了一个简单的logger类,可以作为一个实例,它允许我将信息写入一个文件。前一段时间它在一个示例中工作,但现在抛出了一个空指针异常错误。我真的不知道为什么会这样。我已经把课程代码放在下面了

类别代码:

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Date;

/*This class is a simple logger that currently only has one message but will be added to it in time*/
public class DDHLogger  {
    Date timeStamp = new Date();
    PrintWriter pw = null;
    FileWriter fw;
    File file;

    //FileOutputStream   fstre;  
    //OutputStreamWriter outFileStream;


    /**
     * Used for creating the file when the object is implemented.
     * @param yourstring
     * @param yourfilename
     * @throws IOException -- file check
     */
    public DDHLogger(String filePath, String yourfilename) {
        System.out.println("filePath: " + filePath);
        System.out.println("yourfilename: " + yourfilename);
         //String fileName = "C:\\Users\\home-1\\Desktop\\" + yourfilename;
         String fileName = filePath + yourfilename;
         System.out.println("fileName::--> " + fileName);
        // file = new File(fileName);//Creates the file
         file = new File(fileName);//Creates the file
         System.out.println("file: " + file);
         try {
            fw = new FileWriter(file, true);
        } catch (IOException e) {
            e.printStackTrace();
        }//allows append to the file without over writing. The TRUE keyword is used for append
    }

    /**
     * Must supply two parmaters. The first parmater is the string that is to be written to the file. The second parmater is used for
     * the file name. The extension C: for the default path.
     * @param yourstring
     * @param yourfilename
     */
    void Error(String yourstring, String lineNumber){
        openPrintWriterStream(pw);
        try{
            pw.println("ERROR: " + yourstring + " * " + timeStamp.toString() +" * " + " Line Number: " + lineNumber + "\n");
            pw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }  
    }

    void Debug(String yourstring, String lineNumber){
         openPrintWriterStream(pw);
         try{
             pw.println("DEBUG: " + yourstring + " ******* " + timeStamp.toString() +" ******* " + " Line Number: " + lineNumber + "\n");
             pw.close();
         } catch (Exception e) {
             e.printStackTrace();
         }   
   }

   void Info(String yourstring, String lineNumber) {
       openPrintWriterStream(pw);
       try{
           pw.println("INFORMATION: " + yourstring + " ******* " + timeStamp.toString() +" ******* " + " Line Number: " + lineNumber + "\n");
           pw.close();
       } catch (Exception e) {
           e.printStackTrace();
       } 
   }

   void Warn(String yourstring, String lineNumber){
       openPrintWriterStream(pw);
       try{
           pw.println("Warning: " + yourstring + " ******* " + timeStamp.toString() +" ******* " + " Line Number: " + lineNumber + "\n");
           pw.close();
       } catch (Exception e) {
           e.printStackTrace();
       }    
  }

   void openPrintWriterStream(PrintWriter pw) {
       pw = new PrintWriter(fw);
         try {
            fw = new FileWriter(file, true);
        } catch (IOException e) {
            e.printStackTrace();
        } 
   }
}
空指针异常:

filePath: C:\Users\home-1\Desktop\
yourfilename: PokerLogger.txt
fileName::--> C:\Users\home-1\Desktop\PokerLogger.txt
file: C:\Users\home-1\Desktop\PokerLogger.txt
java.lang.NullPointerException
    at DDHPokerGame.DDHLogger.Info(DDHLogger.java:76)
    at DDHPokerGame.DDHGamePanel$1.mouseEntered(DDHGamePanel.java:150)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.NullPointerException
    at DDHPokerGame.DDHLogger.Info(DDHLogger.java:76)
    at DDHPokerGame.DDHGamePanel$1.mouseExited(DDHGamePanel.java:155)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.NullPointerException
    at DDHPokerGame.DDHLogger.Info(DDHLogger.java:76)
    at DDHPokerGame.DDHGamePanel$1.mouseEntered(DDHGamePanel.java:150)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.NullPointerException
    at DDHPokerGame.DDHLogger.Info(DDHLogger.java:76)
    at DDHPokerGame.DDHGamePanel$1.mouseExited(DDHGamePanel.java:155)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
新的和已清理的代码:

/*This class is a simple logger that currently only has one message but will be added 
  to it in time*/

public class DDHLogger  {
    Date timeStamp = new Date();
    PrintWriter pw = null;
    FileWriter fw = null;
    File file;

    /**
     * Used for creating the file when the object is implemented.
     * @param yourstring
     * @param yourfilename
     * @throws IOException -- file check
     */
    public DDHLogger(String filePath, String yourfilename) {
        System.out.println("filePath: " + filePath);
        System.out.println("yourfilename: " + yourfilename);
         //String fileName = "C:\\Users\\home-1\\Desktop\\" + yourfilename;
         String fileName = filePath + yourfilename;
         System.out.println("fileName::--> " + fileName);
        // file = new File(fileName);//Creates the file
         file = new File(fileName);//Creates the file
         System.out.println("file: " + file);
         try {
            fw = new FileWriter(file, true);
        } catch (IOException e) {
            e.printStackTrace();
        }//allows append to the file without over writing. The TRUE keyword is used for append


    }

    /**
     * Must supply two parmaters. The first parmater is the string that is to be written to the file. The second parmater is used for
     * the file name. The extension C: for the default path.
     * @param yourstring
     * @param yourfilename
     */
    void Error(String yourstring, String lineNumber){

        try{
            pw.println("ERROR: " + yourstring + " * " + timeStamp.toString() +" * " + " Line Number: " + lineNumber + "\n");
        } catch (Exception e) {
            e.printStackTrace();
        }  
    }

    void Debug(String yourstring, String lineNumber){

         try{
             pw.println("DEBUG: " + yourstring + " ******* " + timeStamp.toString() +" ******* " + " Line Number: " + lineNumber + "\n");
         } catch (Exception e) {
             e.printStackTrace();
         }   
   }

   void Info(String yourstring, String lineNumber) {

       try{
           pw.println("INFORMATION: " + yourstring + " ******* " + timeStamp.toString() +" ******* " + " Line Number: " + lineNumber + "\n");
   } catch (Exception e) {
           e.printStackTrace();
       } 
   }

   void Warn(String yourstring, String lineNumber){

       try{
           pw.println("Warning: " + yourstring + " ******* " + timeStamp.toString() +" ******* " + " Line Number: " + lineNumber + "\n");
       } catch (Exception e) {
           e.printStackTrace();
       }    
  }

   void openPrintWriterStream(PrintWriter pw) {
        pw = new PrintWriter(fw);

        try {
            fw = new FileWriter(file, true);
        } catch (IOException e) {
            e.printStackTrace();
        } 
   }

    void closeFile() {
   pw.close();
     }
}
相同的空指针异常:

我更改了代码,但仍然收到相同的空点异常。我甚至不需要PrintWriter pw=null变量

filePath: C:\Users\home-1\Desktop\
yourfilename: subtract.txt
fileName::--> C:\Users\home-1\Desktop\subtract.txt
file: C:\Users\home-1\Desktop\subtract.txt
java.lang.NullPointerException
    at DDHTestBufferedImage.DDHLogger.Debug(DDHLogger.java:62)
    at DDHTestBufferedImage.SubtractBufferedImage.main(SubtractBufferedImage.java:40)

您的
openPrintWriterStream
实际上不会影响名为
pw
的成员变量。另外,由于在方法的最开始重新分配
pw
引用(并且不返回更新的引用),因此分配基本上是无效的。去掉
pw
参数,这样赋值实际上会更新成员变量。您需要进行检查,以确保尚未打开
pw

您正在openPrintWriterStream()方法中“隐藏”pw变量,方法是提供一个与类中字段同名的参数-
pw
。请参见“参数名称”部分:

参数可以与类的某个字段同名。如果是这种情况,则称该参数为字段的阴影。阴影字段会使代码难以阅读,并且通常仅在设置特定字段的构造函数和方法中使用

有几种方法可以解决此问题:

  • 正如matt forsythe所建议的,停止将PrintWriter作为参数传递给openPrintWriterStream(),然后只在它为null时懒洋洋地构造它

  • DDHLogger(String filePath,String yourfilename)
    构造函数中初始化PrintWriter,因为您已经拥有构造PrintWriter所需的所有信息,如下面的代码示例

  • 第二种方法允许您通过删除对
    openPrintWriterStream(pw)
    的所有调用来稍微清理代码


    最后,删除
    DDHLogger()
    或将其设置为私有,因为同一个包中的类仍然可以使用它创建DDHLogger,而不需要所需的
    文件和
    文件编写器
    ,将来可能会导致NullPointerException;请只发布相关部分。你的DDHGamePanel类在哪里?我做了更改,然后将代码放在我最初发布的末尾。当您说取出DDHLOGER()时,零参数构造函数是正确的。我曾经认为Java中必须有一个零参数,否则会抛出编译错误。关闭文件怎么样。我放置了一个方法,允许我关闭文件,或者我甚至应该担心这个问题,因为记录器文件可能应该在每次程序运行时都被更新。我仍然收到空指针异常。我已经在上面的主要帖子中列出了它。关于zero-arg构造函数,有一些情况需要它们,但它们并不总是必需的。关于关闭文件,您可以将closeFile方法公开,并让客户端在完成日志记录后调用该方法以关闭FileWriter。或者,如果您的代码是短期的,您可以让JVM在文件退出时为您关闭该文件(对于长时间运行的生产代码,不建议这样做),关于NPE,您更新的代码仍然没有为
    pw
    ,因此它是空的-我在我的答案中添加了一个示例构造函数,说明了如何执行此操作。
    public DDHLogger(String filePath, String yourfilename) 
    {
        System.out.println("filePath: " + filePath);
        System.out.println("yourfilename: " + yourfilename);
         //String fileName = "C:\\Users\\home-1\\Desktop\\" + yourfilename;
         String fileName = filePath + yourfilename;
         System.out.println("fileName::--> " + fileName);
        // file = new File(fileName);//Creates the file
         file = new File(fileName);//Creates the file
         System.out.println("file: " + file);
         try {
            fw = new FileWriter(file, true);
            //INSTANTIATE PRINTWRITER HERE
            pw = new PrintWriter(fw);
        } catch (IOException e) {
            e.printStackTrace();
        }//allows append to the file without over writing. The TRUE keyword is used for append
    
    }