0

这是我得到的错误代码:

Exception in thread "main" java.lang.StackOverflowError
    at JavaKeywords.<init>(JavaKeywords.java:5)
    at LAddClass.<init>(LAddClass.java:8)
    at LStore.<init>(LStore.java:9)
    at LAddClass.<init>(LAddClass.java:9)
    at LStore.<init>(LStore.java:9)

以下是上面提到的三个类。很抱歉发布几乎整个程序的代码,但我真的不知道错误在哪里。错误代码标记的三行在下面突出显示。

这是一个UML-toJava 转换器程序。用户必须输入类名和类类型(公共/私有),并将变量存储在虚拟类中。我已经创建了一个类对象的 ArrayList 来存储用户的输入、String className 和 boolean isPrivate。稍后必须在 GUI 窗口中打印类名和类型,以便用户复制文本。

我猜该错误与未能将值(String className, String classMethod, boolean isPrivate)存储到ArrayList<LStore>LStore 类的对象的数组列表有关。我之前遇到过空指针异常错误,应该与arraylist有关,在我更改了一些代码和类名之后,我遇到了这个新stackOverFlow错误。

LAddClass class用于使用checkName()并转换bolean isPrivate 为字符串以供以后使用

public class LAddClass{
private String className;
private String methodName;
private boolean isPrivate;

JavaKeywords keyObject = new JavaKeywords(); 

LStore stObject = new LStore(className, methodName,isPrivate);//<<<<<<<<<<<<<<<<<<<<<<<<<<< related to the error

public String getPublic(){
    String s;
    if (stObject.getIsPrivate() == true) 
        s = " private";
    else 
        s = "public";
    return s;
}    
public void setPublic(){

}

public boolean checkName(String name){
    boolean check = true;
    for (int i=0; i<=stObject.getListSize(); i++){

        if (keyObject.containsKeyword(name) || name.equals(stObject.getClassName())){

            boolean o = false;
            check = o;
        }// end if
    }// end for
    return check;
}// end checkName

 }//end class

LStore class是一个用于存储变量的类ArrayList<LStore>

import java.util.*;

public class LStore {

    public static ArrayList<LStore> classes = new ArrayList<LStore>();
    public boolean isPrivate;
        public String className;
        public String methodName;
        LAddClass classObject = new LAddClass(); //<<<<<<<<<<<<<<<<<<<<<<<<<<< related to the error

        public LStore(String name, String method, boolean isP){
        this.className = name;
        this.isPrivate = isP;
        this.methodName = method;
        classes.add(this);
     }

     public String getClassName(){
        return className;
    }    

    public String getMethodName(){
        return methodName;
    }

    public boolean getIsPrivate(){
        return isPrivate;
    }


    public int getListSize(){
        return classes.size();
    }

    public String getJavaCode(){
        String javaCode = (classObject.getPublic() + " " + className +"{\n"+"\t"+methodName+"\t\n}"+"}");
    return javaCode;

    }
}

这里是GuiAddClass用户创建新类的 GUI 类。我认为它也可能包含一些错误,因此我将其放上以供参考。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GuiAddClass extends JFrame{
LAddClass classObject = new LAddClass();

private JRadioButton publicButton, privateButton;
private JLabel clazz;
private JTextField inputClassName;
private JLabel mothod;
private JTextField inputMethodName;
private JLabel note;
private JButton confirmButton;
private JButton cancelButton;

public GuiAddClass(){

    super("Create class");
    setLayout(new FlowLayout());

    publicButton = new JRadioButton("public", false);
    privateButton = new JRadioButton("private", true);
    clazz = new JLabel("Class Name: ");
    inputClassName = new JTextField("ExampleClass",10);
    mothod = new JLabel("Method Name*: ");
    inputMethodName = new JTextField("doSomething()",10);
    note = new JLabel("*All methods are public void in default. You may only create one method for a class.");
    confirmButton = new JButton("Confirm");
    cancelButton = new JButton("Cancel");

    add(publicButton);      
    add(privateButton);     
    add(clazz);     
    add(inputClassName);
    add(mothod);
    add(inputMethodName);
    add(note);
    add(confirmButton);
    add(cancelButton);

    ButtonGroup group = new ButtonGroup();
    group.add(publicButton);
    group.add(privateButton);

    Handler handler = new Handler();
    NewHandler newhandler = new NewHandler();
    confirmButton.addActionListener(handler);
    cancelButton.addActionListener(newhandler);

}// end constructor AddClass()

private class Handler implements ActionListener{

    public void actionPerformed(ActionEvent event){

        String cName = inputClassName.getText();
        String mName = inputMethodName.getText();
        boolean isP = true;

        if (classObject.checkName(cName) == false){

            JOptionPane.showMessageDialog(null, "Class name invalid. " +
                    "\nEntered name should not contain java keywords or equal to other existing names. " +
                    "\nPlease try again."); 

        } else if (classObject.checkName(cName) == true) {

            JOptionPane.showMessageDialog(null, "Class saved."); 
            cName = inputClassName.getText();
            mName = inputMethodName.getText();

            if (event.getSource() == publicButton) {
                isP = false;
            } else if (event.getSource() == privateButton) {
                isP = true;
            }
            new LStore(cName, mName, isP);
        }



    }// end actionPerformed()

}// end Handler class

private class NewHandler implements ActionListener{
    public void actionPerformed(ActionEvent event){
        setVisible(false);
    }
}

   }// end AddClass

JavaKeywords class最初来自如何检查类名是否有效?,一个类,该类具有检查 className 是否等于 java 保留关键字的方法。它也可能与错误有关,因为此类似乎经常被检测为错误

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;

/**
 * JavaKeywords is a Utility class related to the reserved keywords
 *
 * @author MrLore from https://stackoverflow.com/questions/13979172/how-to-check-if-the-class-name-is-valid
 */
public class JavaKeywords 
{
    private static final HashSet<String> keywords = new HashSet(Arrays.asList(new String[]{
    //There are 50 keywords, and 3 literals; true, false and null.
    "abstract",     "assert",        "boolean",      "break",           "byte",
    "case",         "catch",         "char",         "class",           "const",
    "continue",     "default",       "do",           "double",          "else",
    "enum",         "extends",       "false",        "final",           "finally",
    "float",        "for",           "goto",         "if",              "implements",
    "import",       "instanceof",    "int",          "interface",       "long",
    "native",       "new",           "null",         "package",         "private",
    "protected",    "public",        "return",       "short",           "static",
    "strictfp",     "super",         "switch",       "synchronized",    "this",
    "throw",        "throws",        "transient",    "true",            "try",
    "void",         "volatile",      "while"    ,    "string",   "int"
}));

public static boolean isKeyword(String toCheck){ 
    return getKeywords().contains(toCheck);
}//End isKeyword()

public static String[] getAsArray(){
    return getKeywords().toArray(new String[getKeywords().size()]);
}//End getAsArray()

public static ArrayList<String> getAsArrayList(){
    return new ArrayList(getKeywords());
}//End getAsArrayList()

public static HashSet<String> getAsHashSet(){
    return getKeywords();
}//End getAsHashSet()

public static HashSet<String> getKeywords() {
    return keywords;
}//End getKeywords

public boolean containsKeyword(String toCheck){

    toCheck = toCheck.toLowerCase(); //<<<<<<<<<<<<<<<<<<<<<<< this line had been detected as error of null-pointer-exception
    for(String keyword : keywords){
        if(toCheck.equals(keyword) || toCheck.endsWith("." + keyword) ||
           toCheck.startsWith(keyword + ".") || toCheck.contains("." + keyword + ".")){

            return true;
        }//End if
    }//End for
    return false;
}//End containsKeyword()

}//End JavaKeywords

所以这就是所有的代码!我的其他类只是与数据存储无关的 GUI 类,所以我想我不应该发布它们。感谢您阅读我的问题,如果您有任何想法,请帮助:(

4

2 回答 2

1

您可以通过阅读堆栈跟踪找到问题:

  • LJKeywords创建(通过( LJKeywords.<init>LJKeywords.java:10)消息)的实例时出现问题。
  • LAddClass在创建(通过at LAddClass.<init>(LAddClass.java:8)消息)的实例时会发生这种情况。
  • 在创建LStore类的实例时会发生这种情况(通过at LStore.<init>(LStore.java:9)消息)。

然后,通过检查您LAddClassLStore类的构造函数和字段,我发现:

public class LAddClass{
    LJKeywords keyObject = new LJKeywords();
    LStore stObject = new LStore(className, methodName,isPrivate);
    //...
}

public class LStore {
    LAddClass classObject = new LAddClass();
    //...
}

那么,这是在做什么呢?当你创建一个LStore对象引用时,它会在内部创建一个LAddClass对象引用,它在内部会创建一个新的LStore对象引用,它在内部会创建一个LAddClass对象引用,它在内部......好吧,现在你知道这是怎么回事了,有一个无限对象实例化循环在这里。

该怎么做才能解决这个问题?删除这个无限循环后,您可以通过在客户端类中相互分离和关联来创建LAddClass和。LStore例如:

class Client {
    void foo() {
         LAddClass lAddClass = new LAddClass();
         LStore lStore = new LStore();
         lStore.setLAddClass(lAddClass);
         lAddClass.setLStore(lStore);
         //...
    }
}

另外,我建议将您的课程名称更改为更重要的名称。例如,代替LStore、使用Storage和代替LAddClass使用UMLClass(或更合适的名称)。

于 2013-10-27T09:21:48.243 回答
1

问题是,为了创建一个LStore实例,你创建了一个LAddClass- 并且为了创建一个LAddClass实例,你创建了一个LStore实例。所以一个构造函数有效地调用了另一个构造函数,它调用了第一个,等等。这个LJKeywords类在这里是一个红鲱鱼,我认为 - 只是在创建LJKeywords一个新实例时调用了构造函数LAddClass,而这恰好是那根稻草打断了骆驼的后背。

LStore从根本上说,你需要弄清楚你想要的关系如何LAddClass运作。他们不能像这样无条件地互相建设。

我也强烈建议你去掉L所有这些类名的前缀。

于 2013-10-27T09:21:58.240 回答