JavaPoet - 意外异常

JavaPoet - Exception unexpected

所以,我正在制作一个程序,它采用 Class 图,并使用 JavaPoet,将其转换为 Java 代码。

class 图不是用 UML 编写的,它已经在程序中使用 java 建模。

这是给我带来问题的代码部分: (解析class中的所有属性,将它们添加到新的源代码中,如果缺少则添加Setters/Getters)

for (Attribute a : classe.attributes) { //Parse all the attribute inside the class

    TypeName aClass = stringToType(a.getType()); //the attribute tipe

    FieldSpec aField = FieldSpec.builder(aClass, a.getName()) //the attribute
            .addModifiers(javax.lang.model.element.Modifier.valueOf(a.getProtection().toUpperCase()), a.isStatic() ? Modifier.STATIC : null)
            .build();
    fields.add(aField);

    MethodSpec aMethod = MethodSpec.methodBuilder("set" + upperFirst(a.getName()))
            .addModifiers(Modifier.PUBLIC, a.isStatic() ? Modifier.STATIC : null)
            .returns(TypeName.VOID)
            .addParameter(aClass, a.getName())
            .addStatement("this." + a.getName() + " = " + a.getName())
            .build();
    if (!methods.contains(aMethod)) //if not present, add the set method
        methods.add(aMethod);


    MethodSpec bMethod = MethodSpec.methodBuilder("get" + upperFirst(a.getName()))
            .addModifiers(Modifier.PUBLIC, a.isStatic() ? Modifier.STATIC : null)
            .addStatement("return " + a.getName())
            .returns(aClass)
            .build();

    if (!methods.contains(bMethod)) methods.add(bMethod); //if not present, add the get method


}

我在最后一行得到以下异常:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at java.util.EnumSet.typeCheck(EnumSet.java:396)
    at java.util.RegularEnumSet.add(RegularEnumSet.java:161)
    at java.util.RegularEnumSet.add(RegularEnumSet.java:36)
    at java.util.EnumSet.copyOf(EnumSet.java:179)
    at com.squareup.javapoet.CodeWriter.emitModifiers(CodeWriter.java:172)
    at com.squareup.javapoet.MethodSpec.emit(MethodSpec.java:86)
    at com.squareup.javapoet.MethodSpec.toString(MethodSpec.java:164)
    at com.squareup.javapoet.MethodSpec.equals(MethodSpec.java:153)
    at java.util.ArrayList.indexOf(ArrayList.java:317)
    at java.util.ArrayList.contains(ArrayList.java:300)

这是我发布的代码 ->

    at base.controller.commands.ExportModelCommand.execute(ExportModelCommand.java:224)
    at base.Main.executeCommand(Main.java:113)
    at base.controller.menu.menuitem.ItemExport.lambda$new[=12=](ItemExport.java:17)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
    at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
    at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren3(ContextMenuContent.java:1358)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
    at javafx.scene.Scene$MouseHandler.access00(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:380)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent4(GlassViewEventHandler.java:416)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null8(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)

我真的不明白为什么。

我试过调试,在 NULL 找不到任何东西。我如何找到问题?

完整代码 - CLASS模型(省略部分为getters/setters)

public class ClassModel {

    private String name = "";
    private String parent = null;
    public ArrayList<Attribute> attributes = new ArrayList<Attribute>();
    public ArrayList<Method> methods = new ArrayList<Method>();
    public boolean isInterface;
    private boolean isFinal;
    private ProtectionLevel prote;
    private String genericText="";
    private String stereotype="";

    public ClassModel() {
        }

    public ClassModel(ClassModel original) {
        this.name = original.name;
        this.parent = original.parent;
        this.isInterface = original.isInterface;

        /*
        for (Map.Entry<String, Relation> e : original.relations.entrySet()) {
            this.relations.put(e.getKey(), new Relation(e.getValue()));
        }
        */
        for (Attribute a : original.attributes) {
            this.attributes.add(new Attribute(a));
        }
        for (Method m : original.methods) {
            this.methods.add(new Method(m));
        }
    }

完整代码 - 导出命令:

public Message execute() {
    ///////////////////
        /*    Save As    */
    ///////////////////


    // Set tab flag to saved and remove '*' from tab name

    JFileChooser chooser = new JFileChooser();
    chooser.setCurrentDirectory(new File("./"));
    chooser.setDialogTitle("Choose your folder");
    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    chooser.setAcceptAllFileFilterUsed(false);


    if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
        for (Tab tab : Main.project.getTabContainer().getTabs()) {
            BaseDiagramModel currentModel = ((UMLTab) tab).getModel();
            if (currentModel.getDiagramPosition() == 2) {


                for (UMLElement e : currentModel) {
                    if (e instanceof UMLClassElementImage) {
                        //prepare content for new file java


                        ClassModel classe = ((UMLClassElementImage) e).modelClass;


                        ArrayList<MethodSpec> methods = new ArrayList<MethodSpec>();
                        ArrayList<FieldSpec> fields = new ArrayList<FieldSpec>();
                        ArrayList<UMLElement> composition = new ArrayList<UMLElement>();
                        ArrayList<UMLElement> aggregation = new ArrayList<UMLElement>();
                        ArrayList<UMLElement> inheritance = new ArrayList<UMLElement>();
                        for (UMLElement x : ((UMLNode<UMLElement>) e).getChildren()) {
                            if (x instanceof UMLArrowAggregation) {
                                aggregation.add(x);

                            } else if (x instanceof UMLArrowComposition) {
                                composition.add(x);

                            } else if (x instanceof UMLArrowEreditarieta) {
                                inheritance.add(x);

                            }
                            //else if (x instanceof UMLArrowDashedLineWithCentralLabelAndApexOnHead) {
                             //   implementation.add(x);
                            //}
                        }

                        for (UMLElement aggregated : aggregation) {
                            UMLElement whatIsAfterTheArrow = ((UMLNode<UMLElement>) aggregated).getChildren().get(0);
                            ClassModel classeAgg = ((UMLClassElementImage) whatIsAfterTheArrow).modelClass;

                            FieldSpec aField = FieldSpec.builder(ClassName.get("", classeAgg.getName()), classeAgg.getName())
                                    .addModifiers(Modifier.PROTECTED)
                                    .build();
                            fields.add(aField);

                            MethodSpec aMethod = MethodSpec.methodBuilder("set" + upperFirst(classeAgg.getName()))
                                    .addModifiers(Modifier.PUBLIC)
                                    .returns(TypeName.VOID)
                                    .addParameter(ClassName.get("", classeAgg.getName()), classeAgg.getName())
                                    .addStatement("this." + classeAgg.getName() + " = " + classeAgg.getName())
                                    .build();
                            if (!methods.contains(aMethod)) methods.add(aMethod);
                            MethodSpec bMethod = MethodSpec.methodBuilder("get" + upperFirst(classeAgg.getName()))
                                    .addModifiers(Modifier.PUBLIC)
                                    .addStatement("return " + classeAgg.getName())
                                    .returns(ClassName.get("", classeAgg.getName()))
                                    .build();
                            if (!methods.contains(bMethod)) methods.add(bMethod);

                        }

                        for (UMLElement composed : composition) {
                            UMLElement whatIsAfterTheArrow = ((UMLNode<UMLElement>) composed).getChildren().get(0);
                            ClassModel classeComp = ((UMLClassElementImage) whatIsAfterTheArrow).modelClass;

                            FieldSpec aField = FieldSpec.builder(ClassName.get("", classeComp.getName()), classeComp.getName())
                                    .addModifiers(Modifier.PROTECTED, Modifier.FINAL)
                                    .build();
                            fields.add(aField);

                            MethodSpec aMethod = MethodSpec.methodBuilder("set" + upperFirst(classeComp.getName()))
                                    .addModifiers(Modifier.PUBLIC)
                                    .returns(TypeName.VOID)
                                    .addParameter(ClassName.get("", classeComp.getName()), classeComp.getName())
                                    .addStatement("this." + classeComp.getName() + " = " + classeComp.getName())
                                    .build();
                            if (!methods.contains(aMethod)) methods.add(aMethod);
                            MethodSpec bMethod = MethodSpec.methodBuilder("get" + upperFirst(classeComp.getName()))
                                    .addModifiers(Modifier.PUBLIC)
                                    .addStatement("return " + classeComp.getName())
                                    .returns(ClassName.get("", classeComp.getName()))
                                    .build();
                            if (!methods.contains(bMethod)) methods.add(bMethod);

                        }

                        for (Attribute a : classe.attributes) {

                            TypeName aClass = stringToType(a.getType());

                            FieldSpec aField = FieldSpec.builder(aClass, a.getName())
                                    .addModifiers(javax.lang.model.element.Modifier.valueOf(a.getProtection().toUpperCase()), a.isStatic() ? Modifier.STATIC : null)
                                    .build();
                            fields.add(aField);

                            MethodSpec aMethod = MethodSpec.methodBuilder("set" + upperFirst(a.getName()))
                                    .addModifiers(Modifier.PUBLIC, a.isStatic() ? Modifier.STATIC : null)
                                    .returns(TypeName.VOID)
                                    .addParameter(aClass, a.getName())
                                    .addStatement("this." + a.getName() + " = " + a.getName())
                                    .build();
                            if (!methods.contains(aMethod))
                                methods.add(aMethod);


                            MethodSpec bMethod = MethodSpec.methodBuilder("get" + upperFirst(a.getName()))
                                    .addModifiers(Modifier.PUBLIC, a.isStatic() ? Modifier.STATIC : null)
                                    .addStatement("return " + a.getName())
                                    .returns(aClass)
                                    .build();

                            if (!methods.contains(bMethod)) methods.add(bMethod);


                        }

                        for (Method m : classe.methods) {


                            ArrayList<ParameterSpec> parametriSpec = new ArrayList<>();
                            Set<Attribute> parametri = m.getParameters();

                            for (Attribute singleParam : parametri) {
                                TypeName attClass = stringToType(singleParam.getType());


                                ParameterSpec test = ParameterSpec.builder(attClass, singleParam.getName())
                                        // .addModifiers(Modifier.FINAL)
                                        .build();
                                parametriSpec.add(test);
                            }

                            TypeName aClass = stringToType(m.getReturnType());

                            MethodSpec aMethod = MethodSpec.methodBuilder(m.getName())

                                    .addModifiers(javax.lang.model.element.Modifier.valueOf(m.getProtection().toUpperCase()), m.isStatic() ? Modifier.STATIC : null)
                                    .returns(aClass)
                                    .addParameters(parametriSpec)
                                    .build();

                            methods.add(aMethod);
                        }
                        TypeSpec theClass = null;


                        TypeName father = null;
                        if (!inheritance.isEmpty())
                            father = ClassName.get("", ((UMLClassElementImage) ((UMLNode<UMLElement>) inheritance.get(0)).getChildren().get(0)).modelClass.getName());
                        try {



                            theClass = TypeSpec.classBuilder(classe.getName())
                                    .addModifiers(((UMLClassElementImage) e).modelClass.getFinal() ? new Modifier[] { javax.lang.model.element.Modifier.valueOf(classe.getProte().toString().toUpperCase()), Modifier.FINAL} : new Modifier[] { javax.lang.model.element.Modifier.valueOf(classe.getProte().toString().toUpperCase()) })
                                    .addModifiers(javax.lang.model.element.Modifier.valueOf(classe.getProte().toString().toUpperCase()), Modifier.FINAL)
                                    .superclass(father == null ? ClassName.OBJECT : father)
                                    .addMethods(methods)
                                    .addFields(fields)
                                    .build();



                            // Create object to choose and create new file


                        } catch (Exception exc) {

                            getFailureMessage("Il nome della classe potrebbe essere sbagliato?");

                        }


                        try {
                            JavaFile javaFile = JavaFile.builder(currentModel.getTitle(), theClass)
                                    .build();
                            Path javaPath = Paths.get(chooser.getSelectedFile().getPath());
                            javaFile.writeTo(javaPath);

                        } catch (Exception exc) {
                            exc.printStackTrace();
                            return getFailureMessage();

                        }


                    }
                    //Else is not a class
                }


            }


        }
    else if (chooser.showOpenDialog(null) == JFileChooser.CANCEL_OPTION)
        return getFailureMessage("Esportazione annullata");


    // Save jsonArray into a file
    // JsonFileManager jsonFileManager = new JsonFileManager();
    // jsonFileManager.save(jsonArray, Main.project.getName() + ".citro");

    return getSuccessMessage();

}

问题是像这样的行:

.addModifiers(Modifier.PUBLIC, a.isStatic() ? Modifier.STATIC : null)

后来我发现了,但是addModifiers(null)非但没有做任何事情,反而让整个事情爆炸了