线程“main”中的异常 java.lang.StackOverflowError
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16443894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Exception in thread “main” java.lang.StackOverflowError
提问by Morganis
ErrorsWhen i Compile the file I get no errors but when I try to execute this I get the following messages:
错误当我编译文件时,我没有收到任何错误,但是当我尝试执行此文件时,我收到以下消息:
Exception in thread "main" java.lang.StackOverflowError
at sun.awt.SunToolkit.isInstanceOf(SunToolkit.java:1988)
at sun.awt.SunToolkit.isInstanceOf(SunToolkit.java:1997)
at sun.awt.SunToolkit.isInstanceOf(SunToolkit.java:1997)
at sun.awt.SunToolkit.isInstanceOf(SunToolkit.java:1997)
at sun.awt.SunToolkit.isInstanceOf(SunToolkit.java:1997)
at sun.awt.SunToolkit.isInstanceOf(SunToolkit.java:1997)
at sun.awt.SunToolkit.isInstanceOf(SunToolkit.java:1982)
at javax.swing.LookAndFeel.installProperty(LookAndFeel.java:275)
at javax.swing.plaf.basic.BasicButtonUI.installDefaults(BasicButtonUI.java:102)
at javax.swing.plaf.metal.MetalButtonUI.installDefaults(MetalButtonUI.java:80)
at javax.swing.plaf.basic.BasicButtonUI.installUI(BasicButtonUI.java:88)
at javax.swing.JComponent.setUI(JComponent.java:664)
at javax.swing.AbstractButton.setUI(AbstractButton.java:1807)
at javax.swing.JButton.updateUI(JButton.java:146)
at javax.swing.AbstractButton.init(AbstractButton.java:2172)
at javax.swing.JButton.<init>(JButton.java:136)
at javax.swing.JButton.<init>(JButton.java:109)
at Paneel$boven.<init>(Loterij3.java:65)
at Paneel$kies.<init>(Loterij3.java:125)
at Paneel$boven.<init>(Loterij3.java:66)
at Paneel$kies.<init>(Loterij3.java:125)
And then the last lines just repeats themselves many times.
然后最后几行只是重复了很多次。
Question:What do I have to change in my code to make it work?
问题:我必须对代码进行哪些更改才能使其正常工作?
Note:I'm new to Java and I know there are more posts like this one but I just can't apply them to my code with my current limited understanding of Java.
注意:我是 Java 新手,我知道有更多类似的帖子,但由于我目前对 Java 的了解有限,我无法将它们应用到我的代码中。
If someone wants to know: I'm using JCreator.
如果有人想知道:我正在使用 JCreator。
What i'm trying to make:What I'm trying to make is fairly simple.
我正在尝试制作的内容:我尝试制作的内容非常简单。
1)Fill in a name in the JTextField, press enter and the name should appear in the JTextArea. After the name is in the JTextArea the JTextField becomes empty so you can fill another name and so on there should appear a list of names in JTextArea. (this is what I'm now trying to make)
1)在 JTextField 中填写一个名称,按回车键,该名称应该会出现在 JTextArea 中。名称在 JTextArea 中后,JTextField 变为空,因此您可以填写另一个名称,依此类推,JTextArea 中应该会出现一个名称列表。(这就是我现在想要做的)
2)Push the button kiesWin to make the program choose a random person from the list.
2)按下按钮 kiesWin 使程序从列表中随机选择一个人。
3)Push the button resetL to reset the program so I can make a new list to choose a random winner from it.
3)按按钮 resetL 重置程序,这样我就可以创建一个新列表,从中随机选择一个获胜者。
The whole code:
整个代码:
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
// Main method to make the frame
public class Loterij3 extends JFrame {
public static void main( String args[] ) {
JFrame frame = new Loterij3();
frame.setExtendedState( frame.MAXIMIZED_BOTH );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setTitle( "Klanten Register" );
frame.setContentPane( new Paneel() );
frame.setVisible( true );
}
}
class Paneel extends JPanel {
private boven Boven;
JTextArea textvak1;
JTextField textvak2;
OnthoudNaam onthoudNaam = new OnthoudNaam();
public Paneel() {
setLayout( new BorderLayout() ); // using border Layout.
setBackground( Color.LIGHT_GRAY );
textvak1 = new JTextArea();
add( new JScrollPane( textvak1 ) );
textvak1.setBackground( Color.WHITE );
textvak2 = new JTextField();
textvak2.setHorizontalAlignment(JTextField.CENTER);
textvak2.setEditable( false );
Boven = new boven();
add( Boven, BorderLayout.NORTH );
add( textvak1, BorderLayout.CENTER );
add( textvak2, BorderLayout.SOUTH );
}
class boven extends JPanel {
JButton kiesWin, resetL;
JLabel label1;
JTextField invoervak1;
public boven() {
setBackground( Color.LIGHT_GRAY );
setLayout( new GridLayout( 1, 4, 100, 5 ) ); // using GridLayout.
Border border =
BorderFactory.createEmptyBorder( 10, 10, 10, 10 );
setBorder( border );
kiesWin = new JButton("Kies een Winnaar!");
kiesWin.addActionListener( new kies() );
resetL = new JButton("Reset alles");
resetL.addActionListener( new reset() );
label1 = new JLabel("Voer Persoon in en druk op enter: ", JLabel.RIGHT);
invoervak1 = new JTextField( 20 );
invoervak1.addActionListener( new InvoerVakHandler() );
add( label1 );
add( invoervak1 );
add( kiesWin );
add( resetL );
}
}
// de naam
class naam {
private String ingevoerdNaam;
public naam( String ingevoerdNaam) {
this.ingevoerdNaam = ingevoerdNaam;
}
public String getIngevoerdNaam() {
return ingevoerdNaam;
}
}
// Arraylist
class OnthoudNaam extends JPanel {
private ArrayList<naam> lijst;
public OnthoudNaam() {
lijst = new ArrayList<naam>();
}
public void voegNaamToe(naam x ) {
lijst.add(x);
}
public String toString() {
StringBuffer buffer = new StringBuffer();
for(naam x : lijst ) {
buffer.append( x );
buffer.append( "\n" );
}
return buffer.toString();
}
}
// invoer handler
public class InvoerVakHandler extends boven implements ActionListener {
public void actionPerformed( ActionEvent e ) {
String invoer = invoervak1.getText();
naam naam = new naam( invoer );
onthoudNaam.voegNaamToe( naam );
textvak1.setText( onthoudNaam.toString() );
}
}
// kies
class kies extends boven implements ActionListener {
public void actionPerformed( ActionEvent e ) {
}
}
// reset
class reset extends boven implements ActionListener {
public void actionPerformed( ActionEvent e ) {
}
}
}
For everyone who is trying to help me: Thank you for all your help and patience in advance!
对于所有试图帮助我的人:提前感谢您的所有帮助和耐心!
回答by Daniel Fischer
In the constructor of boven
, you call
在 的构造函数中boven
,您调用
kiesWin.addActionListener( new kies() );
the constructor of kies
, but
的构造函数kies
,但是
class kies extends boven implements ActionListener {
that constructor calls the constructor of boven
. You have an infinite recursion.
该构造函数调用 的构造函数boven
。你有一个无限递归。
回答by Jon S.
A StackOverflowError means that you have too many function calls to fit their data on the stack. Usually it's an indication that you have infinite recursion going on, as you do in this case.
StackOverflowError 意味着你有太多的函数调用来适应堆栈中的数据。通常这表明您正在进行无限递归,就像您在这种情况下所做的那样。
When you create a "boven," it creates a new "kies." But kies extends boven, so you wind up creating a boven which creates a kies which creates a boven which creates a kies which eventually blows up the stack.
当您创建“boven”时,它会创建一个新的“kies”。但是 kies 扩展了 boven,所以你最终创建了一个 boven,它创建了一个 kies,它创建了一个 boven,它创建了一个最终炸毁堆栈的 kies。
To fix this, kies should probably not be a boven.
为了解决这个问题,kies 可能不应该是 boven。
回答by Jon Skeet
This is the problem:
这就是问题:
// Constructor for the boven class
public boven() {
...
kiesWin.addActionListener( new kies() );
...
}
...
class kies extends boven {
}
So to create an instance, of boven
, you have to create an instance of kies
... but as kies
extends boven
, creating an instance of kies
ends up back in the constructor of boven
, which creates another instance of kies
etc.
因此,要创建一个实例中boven
,你必须创建的实例kies
...但作为kies
延伸boven
,打造的一个实例kies
结束了在构造函数后面boven
它创建的另一个实例,kies
等等。
It's not clear whykies
extends boven
in the first place - I suspect it shouldn't.
目前尚不清楚为什么首先kies
扩展boven
- 我怀疑它不应该。
It's not actually clear to me what your code is trying to achieve (it's hard to read, so I haven't looked in too much detail) but I have general suggestions:
我实际上不清楚你的代码想要实现什么(它很难阅读,所以我没有看太多细节)但我有一般的建议:
- Start following Java naming conventions (capitalize your class names, for example)
- Avoid nested classes - generally prefer create top level classes
- Avoid doing so much work in constructors
- Prefer composition to inheritance
- 开始遵循 Java 命名约定(例如,将类名大写)
- 避免嵌套类 - 通常更喜欢创建顶级类
- 避免在构造函数中做太多工作
- 更喜欢组合而不是继承
回答by Andrzej Doyle
It's quite simple really.
这真的很简单。
To construct an instance of boven
, you need to construct an instance of kies
to act as the action listener for the "Kies een Winnaar" button.
要构造 的实例boven
,您需要构造 的实例kies
来充当“Kies een Winnaar”按钮的动作侦听器。
However, kies
is a subclass of boven
, and so it involves the same constructor. So to contruct a boven
, you need to construct a boven
, which means constructing a boven
, which means constructing a boven
...
但是,kies
是 的子类boven
,因此它涉及相同的构造函数。因此,要构造 a boven
,您需要构造 a boven
,这意味着构造 a boven
,这意味着构造boven
...
The only way to fix this is to break the infinite cycle. A boven
object cannotrely on another instance existing in its only constructor, else it's impossible to create. It seems like your class hierarchy may be wrong, since it doesn't like an action listener would need to be the same class that is creating the buttons in the first place. If you just remove the subclass relationship, I believe things would work as you intended.
解决这个问题的唯一方法是打破无限循环。一个boven
对象不能依赖于它唯一的构造函数中存在的另一个实例,否则就不可能创建。看起来您的类层次结构可能是错误的,因为它不希望动作侦听器与首先创建按钮的类相同。如果您只是删除子类关系,我相信事情会如您所愿。
回答by Rick Barkhouse
kies is a subclass of boven. So, when you are creating a new kies, which is what this indicates:
kies 是 boven 的一个子类。所以,当你创建一个新的 kies 时,这表明:
Paneel$kies.<init>
the constructor of boven gets run. boven's constructor creates a new kies. So you get an infinite loop.
boven 的构造函数开始运行。boven 的构造函数创建了一个新的 kies。所以你得到一个无限循环。