【问题标题】:Java: Cannot be Referenced From a Static ContextJava:不能从静态上下文中引用
【发布时间】:2014-04-21 21:25:51
【问题描述】:

我正在尝试用一个面板制作一个框架,该面板由位于框架底部的两个按钮组成。

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 不能从静态上下文中引用

我该如何解决?

【问题讨论】:

  • 你真的不应该以大写字母开头的变量名,它读起来很混乱,也会让编译器感到困惑。
  • @HarryBlargle 我觉得它读起来很混乱,但我希望没有 Java 编译器会与它混淆 ^^
  • @xav 它可能认为您在静态上下文中使用 java.awt.Frame
  • @HarryBlargle +1,没有注意到 :) IDE 可能确实会自动导入 AWT 类(尽管编译器不会混淆)

标签: java swing jframe


【解决方案1】:

你可以这样做:

JFrame Frame = new ControlledBall().new Viewer();

代替:

JFrame Frame = new Viewer();

但我不确定这是否真的是您想要的,因为 ControlledBallJPanel...

【讨论】:

    【解决方案2】:

    非静态内部类的实例持有指向其封闭对象的指针,以便能够引用其成员。参见例如 Java inner class and static nested class 一个副作用是它们不能从静态方法中实例化,静态方法与封闭类的实际实例无关,除非通过实例化 ControlledBall 类的中间对象。

    PS:要记住这个隐式this 指针的另一个副作用(与您的用例不太相关)是它可能导致资源泄漏,因为只要内部实例存在,它就会使外部实例保持活动状态。

    【讨论】:

      【解决方案3】:

      您在 ControlledBall 类中创建了一个公共内部类,这就是您无法访问它的原因,因为您没有 ControlledBall 类的实例。

      不过,从缩进和您的代码猜测,您可能打算创建两个单独的类并从ControlledBall 的主要方法实例化Viewer 类。为此,请将 Viewer 类移动到其自己的名为 Viewer.java 的文件中,它应该可以工作。

      【讨论】:

        【解决方案4】:

        “main”方法是静态的,在执行时,它的“包含”类可能尚未实例化,因此类 Viewer 可能还不存在。由于这个示例显然是程序的入口点,“查看器”肯定还不存在。

        有很多方法可以解决这个问题,例如创建一个 ControlledBall 实例,然后使用该实例创建“查看器”。

        通过实例化“main”容器的实例然后从那里运行,尽快在 Java 程序中“摆脱静态”是我的个人风格。我被告知“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();
        }
        

        因为 Thread,我使用“运行”。我知道这可以扔很多飞镖,这只是一个例子。

        【讨论】:

          【解决方案5】:

          使内部类(查看器)静态 public static class Viewer extends JFrame 你不能从静态方法访问非静态的东西

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-04-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多