Java 空指针异常,我不确定原因

Java 空指针异常,我不确定原因,java,xml,file-io,nullpointerexception,Java,Xml,File Io,Nullpointerexception,这个问题很复杂,所以我会尽我所能把每件事都说清楚,如果我需要从这篇文章中详细说明任何事情或删除任何不相关的内容,请告诉我。我的程序用于读取一个XML文件并打印一个包含两个产品的数组,这两个产品是从XML文件中恢复3次的数据,在数组第一次打印后向数组中添加第三个元素,并在数组第二次打印后将其删除。程序会告诉用户何时添加或删除第三个元素,这意味着所需的输出是正确的 Product list: code of the first product name of the first product

这个问题很复杂,所以我会尽我所能把每件事都说清楚,如果我需要从这篇文章中详细说明任何事情或删除任何不相关的内容,请告诉我。我的程序用于读取一个XML文件并打印一个包含两个产品的数组,这两个产品是从XML文件中恢复3次的数据,在数组第一次打印后向数组中添加第三个元素,并在数组第二次打印后将其删除。程序会告诉用户何时添加或删除第三个元素,这意味着所需的输出是正确的

Product list:
code of the first product   name of the first product       price of the first product
code of the second product   name of the second product     price of the second product

XML Tester has been added to the XML document 


Product list:
code of the first product   name of the first product       price of the first product
code of the second product   name of the second product     price of the second product
code of the XML tester       name of the XMl tester         price of the XML tester

XML tester has been deleted from the XML document.


Product list:
code of the first product   name of the first product       price of the first product
code of the second product   name of the second product     price of the second product
然而,在第一次之后,我在第二次使用新添加的测试仪打印产品时遇到了一个空指针异常错误

这发生在我的代码的第67行,如下所示,以使错误发生的地方更加明显,并使其更清楚

p.setDescription(description);
我的调试器所说的描述此时设置为“Murach的开始Java”,我不确定为什么这是一个空指针,因为这个确切的描述在我的程序第一次打印到控制台时起作用

下面是我的程序的样子,以及我在调试程序时注意到的一些事情,以使这个问题更容易解决

import java.util.ArrayList;
import java.io.*;
import javax.xml.stream.*;  // StAX API

public class XMLTesterApp
{
    private static String productsFilename = "products.xml";

    public static void main(String[] args)
    {
        **This first part the XML file contains two values and it prints both fine*****
        System.out.println("Products list:");
        ArrayList<Product> products = readProducts();
        printProducts(products);

        *** This part adds a tester line to the print out and this is the point the 
        *** null pointer exception error starts to happen This is used as a test to
        *** make sure my file writer method is working by an instructor and the program
        ***  is supposed to fail here if I am doing something wrong but I can't figure
        ***  out what im doing wrong ************************
        Product p1 = new Product("test", "XML Tester", 77.77);
        products.add(p1);
        writeProducts(products);
        System.out.println("XML Tester has been added to the XML document.\n");


        System.out.println("Products list:");
        products = readProducts();
        printProducts(products);


        products.remove(2);
        writeProducts(products);
        System.out.println("XML Tester has been deleted from the XML document.\n");


        System.out.println("Products list:");
        products = readProducts();
        printProducts(products);

    }

   private static ArrayList<Product> readProducts()
{
    ArrayList<Product> products = new ArrayList<>();
    Product p = null;
    XMLInputFactory inputFactory = XMLInputFactory.newFactory();
    try
    {
        //create a stream reader object
        FileReader fileReader = new FileReader("products.xml");
        XMLStreamReader reader = inputFactory.createXMLStreamReader(fileReader);
        //read XML file
        while (reader.hasNext())
        {
          int eventType = reader.getEventType();
          switch (eventType)
          {
               case  XMLStreamConstants.START_ELEMENT :
                  String elementName = reader.getLocalName();
                  //get the product and its code
                  if (elementName.equals("Product"))
                  {
                     p = new Product();
                     String code = reader.getAttributeValue(0);
                     p.setCode(code);
                  }   
                  // get the product description
                  if (elementName.equals("Description"))
                  {
                     String description = reader.getElementText();
                     ************Error occurs on the line under this note*************
                     p.setDescription(description);

                  }    
                  // get the product price
                  if (elementName.equals("Price")) 
                  {

                      String priceS = reader.getElementText();
                      double price = Double.parseDouble(priceS);
                      **** As I test I removed the set descirption line and then 
                           this line returned the same error that that line
                           did*********************************************
                      p.setPrice(price);
                  }    
                  break;
               case XMLStreamConstants.END_ELEMENT :
                  elementName = reader.getLocalName();
                  if(elementName.equals("Product"))
                  {
                    products.add(p);  
                  }    
                  break; 
              }
         reader.next();
        }    
    }
    catch (IOException | XMLStreamException e)
    {
      System.out.println(e); 
    }    
     return products;
    }

    private static void writeProducts(ArrayList<Product> products)
    {
      XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
        try
        {
            //create a stream reader object
            FileWriter fileWriter = new FileWriter("products.xml");
            XMLStreamWriter writer = outputFactory.createXMLStreamWriter(fileWriter);
            //write to the XML file
            writer.writeStartDocument("1.0");
            writer.writeStartElement("Products");
            for (Product p : products)
            {
                writer.writeStartElement("Prodcut");
                writer.writeAttribute("Code", p.getCode()) ;
                writer.writeStartElement("Description");  
                writer.writeCharacters(p.getDescription());
                writer.writeEndElement();
                writer.writeStartElement("Price");
                double price = p.getPrice();
                writer.writeCharacters(Double.toString(price));
                writer.writeEndElement();
                writer.writeEndElement();
            }
            writer.writeEndElement();
            writer.flush();
            writer.close();
        }  
        catch (IOException | XMLStreamException e)
        {
           System.out.println("e"); 
        }
    }

    private static void printProducts(ArrayList<Product> products)
    {
        for (Product p : products)
        {
            printProduct(p);
        }
        System.out.println();
    }

    private static void printProduct(Product p)
    {
        String productString =
            StringUtils.padWithSpaces(p.getCode(), 8) +
            StringUtils.padWithSpaces(p.getDescription(), 44) +
            p.getFormattedPrice();

        System.out.println(productString);
    }
}
import java.util.ArrayList;
导入java.io.*;
导入javax.xml.stream.*;//斯塔克斯API
公共类XMLTesterApp
{
私有静态字符串productsFilename=“products.xml”;
公共静态void main(字符串[]args)
{
**XML文件的第一部分包含两个值,它可以很好地打印这两个值*****
System.out.println(“产品列表”);
ArrayList products=readProducts();
印刷品(产品);
***本部分在打印输出中添加了一行测试仪,这就是
***开始出现空指针异常错误。此错误用于测试
***确保我的文件编写器方法由讲师和程序执行
***如果我做错了什么,应该会失败,但我不明白
***找出我做错了什么************************
产品p1=新产品(“测试”,“XML测试仪”,77.77);
产品。添加(p1);
书面产品(产品);
System.out.println(“XML测试仪已添加到XML文档中。\n”);
System.out.println(“产品列表”);
products=readProducts();
印刷品(产品);
产品。移除(2);
书面产品(产品);
System.out.println(“XML测试仪已从XML文档中删除。\n”);
System.out.println(“产品列表”);
products=readProducts();
印刷品(产品);
}
私有静态ArrayList readProducts()
{
ArrayList产品=新的ArrayList();
乘积p=null;
XMLInputFactory inputFactory=XMLInputFactory.newFactory();
尝试
{
//创建流读取器对象
FileReader FileReader=newfilereader(“products.xml”);
XMLStreamReader=inputFactory.createXMLStreamReader(fileReader);
//读取XML文件
while(reader.hasNext())
{
int eventType=reader.getEventType();
开关(事件类型)
{
案例XMLStreamConstants.START_元素:
String elementName=reader.getLocalName();
//获取产品及其代码
if(elementName.equals(“产品”))
{
p=新产品();
字符串代码=reader.getAttributeValue(0);
p、 setCode(代码);
}   
//获取产品描述
if(elementName.equals(“Description”))
{
字符串描述=reader.getElementText();
************此注释下的行出现错误*************
p、 设置描述(描述);
}    
//了解产品价格
if(elementName.equals(“价格”))
{
字符串价格=reader.getElementText();
双倍价格=double.parseDouble(价格);
****当我测试时,我删除了设置描述行,然后
此行返回的错误与该行相同
做过*********************************************
p、 设定价格(价格);
}    
打破
案例XMLStreamConstants.END_元素:
elementName=reader.getLocalName();
if(elementName.equals(“产品”))
{
产品.加入(p);;
}    
打破
}
reader.next();
}    
}
捕获(IOException | XMLStreamException e)
{
系统输出打印ln(e);
}    
退货产品;
}
私有静态void writeProducts(ArrayList产品)
{
XMLOutputFactory outputFactory=XMLOutputFactory.newFactory();
尝试
{
//创建流读取器对象
FileWriter FileWriter=newfilewriter(“products.xml”);
XMLStreamWriter writer=outputFactory.createXMLStreamWriter(fileWriter);
//写入XML文件
writer.writeStartDocument(“1.0”);
作者:书面财产(“产品”);
对于(产品p:产品)
{
writer.writeStarElement(“Prodcut”);
writeAttribute(“Code”,p.getCode());
作者。书面声明(“说明”);
writeCharacters(p.getDescription());
writer.writeedelement();
作者:书面财产(“价格”);
双倍价格=p.getPrice();
writeCharacters(Double.toString(price));
书面删除(
  writer.writeStartElement("Prodcut");
 if (elementName.equals("Product"))