Java:无法从静态上下文引用
我试着用一个面板制作一个框架,面板由位于框架底部的两个按钮组成Java:无法从静态上下文引用,java,swing,jframe,Java,Swing,Jframe,我试着用一个面板制作一个框架,面板由位于框架底部的两个按钮组成 public class ControlledBall extends JPanel { public static void main(String[] args) { JFrame Frame = new Viewer(); Frame.setSize(1000, 500); Frame.setTitle("Bouncing Ball"); Frame.
public class ControlledBall extends JPanel {
public static void main(String[] args) {
JFrame Frame = new Viewer();
Frame.setSize(1000, 500);
Frame.setTitle("Bouncing Ball");
Frame.setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
Frame.setVisible(true);
}
public class Viewer extends JFrame {
JButton buttonGo = new JButton("GO");
JButton buttonStop = new JButton("STOP");
JPanel aPanel = new JPanel();
public Viewer() {
aPanel.add(buttonGo);
aPanel.add(buttonStop);
this.add(aPanel, BorderLayout.SOUTH);
}
}
}
这里的问题是:
JFrame Frame = new Viewer();
它在告诉我
ControlledBall.this不能从静态上下文引用
如何修复它?使内部类查看器保持静态 公共静态类查看器扩展了JFrame
不能从静态方法访问非静态内容使内部类查看器成为静态 公共静态类查看器扩展了JFrame
您无法从静态方法访问非静态内容您可以执行以下操作:
JFrame Frame = new ControlledBall().new Viewer();
而不是:
JFrame Frame = new Viewer();
但我不确定这是否真的是您想要的,因为Controlled Ball是JPanel…您可以执行以下操作:
JFrame Frame = new ControlledBall().new Viewer();
而不是:
JFrame Frame = new Viewer();
但我不确定这是否真的是您想要的,因为Controlled Ball是一个JPanel…非静态内部类的实例持有指向其封闭对象的指针,以便能够引用其成员。例如,请参见一个副作用,即它们不能从静态方法中恢复,而静态方法与封闭类的实际实例没有任何关系,除非通过恢复ControlledBall类的中间对象
PS:另一个与此隐式指针的用例不太相关的副作用是,它可能导致资源泄漏,因为它使外部实例在内部实例存在时保持活动状态。非静态内部类的实例持有指向其封闭对象的指针,以便能够引用其成员。例如,请参见一个副作用,即它们不能从静态方法中恢复,而静态方法与封闭类的实际实例没有任何关系,除非通过恢复ControlledBall类的中间对象
PS:另一个与此隐式指针的用例不太相关的副作用是,它可能导致资源泄漏,因为它使外部实例在内部实例存在时保持活动状态。您已经在ControlledBall类内创建了一个公共内部类,这就是您无法访问它的原因,因为您没有ControlledBall类的实例
从缩进和代码中猜测,您可能想做的是创建两个独立的类,并从ControlledBall的主方法实例化查看器类。为此,请将查看器类移动到它自己的名为Viewer.java的文件中,它应该可以工作。您已经在ControlledBall类中创建了一个公共内部类,这就是为什么您无法访问它,因为您没有ControlledBall类的实例
从缩进和代码中猜测,您可能想做的是创建两个独立的类,并从ControlledBall的主方法实例化查看器类。为此,请将查看器类移动到其自己的名为Viewer.java的文件中,它应该可以工作。主方法是静态的,执行时,其包含的类可能尚未实例化,因此类查看器可能还不存在。因为这个例子显然是程序的入口点,所以查看器肯定还不存在 有许多方法可以解决此问题,例如创建ControlledBall的实例,然后使用该实例创建查看器 我个人的风格是在Java程序中通过实例化一个mains容器实例,然后从那里运行,尽快摆脱静态。我被教导,main是静态的,所以它的存在是为了被父系统调用,并且没有更多的用途,我相信还有其他的观点。下面是一个简短的示例,缺少很多细节:
public static void main(String[] args) {
// Pass 'args' to which ever method you prefer
ControlledBall app = new ControlledBall(args);
app.run(args);
}
private void run(String[] args) {
JFrame Frame = new Viewer();
}
我使用“run”是因为线程。我知道在这一点上可能会抛出许多省道,这只是一个例子。主方法是静态的,执行时,其包含的类可能尚未实例化,因此类查看器可能还不存在。因为这个例子显然是程序的入口点,所以查看器肯定还不存在 有许多方法可以解决此问题,例如创建ControlledBall的实例,然后使用该实例创建查看器 我个人的风格是在Java程序中通过实例化一个mains容器实例,然后从那里运行,尽快摆脱静态。我被教导,main是静态的,所以它的存在是为了被父系统调用,并且没有更多的用途,我相信还有其他的观点。下面是一个简短的示例,缺少很多细节:
public static void main(String[] args) {
// Pass 'args' to which ever method you prefer
ControlledBall app = new ControlledBall(args);
app.run(args);
}
private void run(String[] args) {
JFrame Frame = new Viewer();
}
我使用“run”是因为线程。我知道在这个问题上可能会有很多困难,这只是一个例子。你真的不应该用大写字母来开始变量名,它让人读起来很困惑,而且也会让编译器感到困惑。@HarryBlagle我认为读起来很困惑,但是我希望没有Java编译器会与^^@xav混淆,它可能会认为您在静态环境中使用Java.awt.Framecontext@HarryBlargle+1,没有注意到:IDE可能会自动导入AWT c
lasses虽然编译器不会被混淆,但可能的重复您确实不应该以大写字母开始变量名,这很容易混淆,而且也会混淆编译器。@Harrybalagle我认为它很容易混淆,但是我希望没有Java编译器会与^^@xav混淆,它可能会认为您在静态环境中使用Java.awt.Framecontext@HarryBlargle+1,没有注意到:IDE可能确实会自动导入AWT类,尽管编译器不会混淆可能的重复