本文介紹了可能與類對象ArrayList數(shù)據(jù)存儲相關的未知StackOverflow錯誤(&A的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
以下是我收到的錯誤代碼:
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)
下面是上面提到的三個類。很抱歉發(fā)布了幾乎整個程序的代碼,但我真的不知道錯誤在哪里。下面突出顯示了錯誤代碼生成的三行代碼。
這是一個UMLtoJava轉換器的程序。用戶必須輸入類名和類類型(公共/私有),并將變量存儲在虛擬類中。我已經(jīng)創(chuàng)建了一個類Object的ArrayList來存儲用戶的輸入,即字符串className和布爾值isPrivate。稍后,必須在圖形用戶界面窗口中打印類名和類型,以便用戶復制文本。
我猜錯誤與無法將值(String className, String classMethod, boolean isPrivate
)存儲到ArrayList<LStore>
有關,ArrayList<LStore>
是LStore類的對象的arrayList。我以前遇到過一個空指針異常錯誤,它應該與數(shù)組列表有關,在我更改了一些代碼和類名之后,我得到了這個新的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 +"{
"+" "+methodName+"
}"+"}");
return javaCode;
}
}
和這里的圖形用戶界面類GuiAddClass
供用戶創(chuàng)建新類。我認為它也可能包含一些錯誤,所以我會把這個放在上面以供參考。
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. " +
"
Entered name should not contain java keywords or equal to other existing names. " +
"
Please 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
最初來自How to check if the class name is valid?,這個類的方法是檢查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
這就是所有的代碼!!我的其他類只是圖形用戶界面類,與數(shù)據(jù)存儲無關,所以我想我不應該發(fā)布它們。感謝您閱讀我的問題,如果您有任何想法,請幫助:(
推薦答案
您可以通過閱讀堆棧跟蹤來發(fā)現(xiàn)問題:
創(chuàng)建LJKeywords
的實例時出現(xiàn)問題(由在LJKeywords.<init>
(LJKeywords.Java:10)消息創(chuàng)建)。
創(chuàng)建LAddClass
(通過在LAddClass.<init>
(LAddClass.java:8)消息)的實例時發(fā)生的錯誤。
創(chuàng)建LStore
類的實例時(通過atLStore.<init>
(LStore.java:9)消息)。
然后,通過檢查LAddClass
和LStore
類構造函數(shù)和字段,我發(fā)現(xiàn):
public class LAddClass{
LJKeywords keyObject = new LJKeywords();
LStore stObject = new LStore(className, methodName,isPrivate);
//...
}
public class LStore {
LAddClass classObject = new LAddClass();
//...
}
那么,這是做什么的?當您創(chuàng)建LStore
對象引用時,它將在內部創(chuàng)建LAddClass
對象引用,該對象引用將在內部創(chuàng)建新的LStore
對象引用,該對象引用將在內部創(chuàng)建LAddClass
對象引用。好了,現(xiàn)在您知道這是怎么回事了,這里有一個無限對象實例化循環(huán)。
如何解決此問題?移除這個無限循環(huán)后,您可以通過在客戶端類中分離和關聯(lián)來創(chuàng)建LAddClass
和LStore
。例如:
class Client {
void foo() {
LAddClass lAddClass = new LAddClass();
LStore lStore = new LStore();
lStore.setLAddClass(lAddClass);
lAddClass.setLStore(lStore);
//...
}
}
此外,我建議將您的類的名稱更改為更重要的名稱。例如,用LStore
代替Storage
,用LAddClass
代替UMLClass
(或更合適的名稱)。
這篇關于可能與類對象ArrayList數(shù)據(jù)存儲相關的未知StackOverflow錯誤(&A的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,