首页 > 解决方案 > 在 Java 中创建新的 JAXBContext 实例时出现 NullPointerException

问题描述

我有一个类可以将我的对象输出到 XML,反之亦然。我这样做的方法是使用带有 try/catch 的 JAXB。

当我运行程序时,我收到错误:

New Drawing object could not me instaned.Exception in thread "main" java.lang.NullPointerException
at se.miun.vife1700.dt062g.jpaint.FileHandler.saveToXML(FileHandler.java:21)
at se.miun.vife1700.dt062g.jpaint.Main.testDrawing(Main.java:53)
at se.miun.vife1700.dt062g.jpaint.Main.main(Main.java:21)

似乎我必须写 JAXBContext context = null; 在尝试捕获之前。但是我如何以不同的方式做到这一点?当我抛出异常时,程序不会继续执行吗?我是 JAVA 新手,尤其是例外。

任何形式的帮助表示赞赏。

    import javax.xml.bind.*;
import java.io.File;
import java.util.Objects;


public class FileHandler {

    public static void saveToXML (Drawing drawing, String fileName) {

        JAXBContext context = null;
        try {
            context = JAXBContext.newInstance(Drawing.class);
        } catch (JAXBException e) {
            System.err.print("New Drawing object could not be instanced.");
        }
        Marshaller marshaller = null;
        try {
            marshaller = context.createMarshaller();
        } catch (JAXBException e) {
            System.err.print("Could not create a Marshaller");
        }

        try {
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        } catch (PropertyException e) {
            System.err.print("A problem occurred when setting output format");
        }

        if(Objects.equals(".xml", fileName.substring(fileName.length() - 4))) {

            try {
                marshaller.marshal(drawing, new File(fileName));
            } catch (JAXBException e) {
                System.err.print("An error occurred when saving to file.");
            }
        }
        else {

            fileName += ".xml";
            try {
                marshaller.marshal(drawing, new File(fileName));
            } catch (JAXBException e) {
                System.err.print("An error occurred when saving to file.");
            }
        }

    }


    public static Drawing loadFromXML(String fileName){

        Drawing drawing = null;
        JAXBContext context = null;
        try {
            context = JAXBContext.newInstance(Drawing.class);
        } catch (JAXBException e) {
            System.err.print("New Drawing object could not be instanced.");
        }
        Unmarshaller unmarshaller = null;
        try {
            unmarshaller = context.createUnmarshaller();
        } catch (JAXBException e) {
            System.err.print("Could not create a Unmarshaller");
        }

        try {
            drawing = (Drawing) unmarshaller.unmarshal(
                    new File(fileName)
            );
        } catch (JAXBException e) {
            System.err.print("An error occurred when loading from file.");
        }

        return drawing;
    }


}

提前致谢。

标签: javajaxb

解决方案


你的做法没有意义。想一想:

    JAXBContext context = null;
    try {
        context = JAXBContext.newInstance(Drawing.class);
    } catch (JAXBException e) {
        System.err.print("New Drawing object could not be instanced.");
    }

如果在尝试创建上下文时抛出 JAXBException,则上下文保持其原始值:null。那么执行下一行时会发生什么?

    Marshaller marshaller = null;
    try {
        marshaller = context.createMarshaller();
    } catch (JAXBException e) {
        System.err.print("Could not create a Marshaller");
    }

保证会抛出 NullPointerException。尝试使用无法创建的上下文,并假装没有引发异常,这是没有意义的。此外,这实际上是在打自己的脚,因为控制台中没有实际的错误消息和堆栈跟踪,而是准确地告诉您出了什么问题,您只有一个模糊的“无法创建编组器”,这使得它不可能知道为什么无法创建编组器。

此方法不应捕获异常,因为它无法正确处理它们。它应该简单地传播它们。或者至少,如果你想将调用者与血腥的 XML 细节隔离开来,你应该重新抛出一个自定义(或其他标准)异常:

try {
    // all the code here
}
catch (JAXBException e) {
    throw new FileHandlingException("Error while saving file", e);
}

这更好,因为调用者现在知道文件无法保存并且可以采取相应的行动(例如通过停止程序,或询问用户他想做什么),而不是继续并表现得好像没什么坏事发生了。


推荐阅读