“非静态变量无法从静态上下文中引用”的解决方法是什么?

时间:2013-02-18 07:11:27

标签: java oop javabeans static-methods idioms

将方法或匿名内部类以某种方式放入驱动程序类的主方法中有一个特殊的习惯用法:

package net.bounceme.dur.misc;

import net.bounceme.dur.misc.Foo;

public class StaticRef {

    Foo f = Foo.INSTANCE;

    public static void main(String[] args) throws Exception {

        f.connect();  //move this to inside "run"
        /*
        public void run(){
           StaticRef sf = new StaticRef();
           //do stuff here
        }
         */
    }
}

以防止出现以下错误:

init:
Deleting: /home/thufir/NetBeansProjects/nntp/build/built-jar.properties
deps-jar:
Updating property file: /home/thufir/NetBeansProjects/nntp/build/built-jar.properties
Compiling 1 source file to /home/thufir/NetBeansProjects/nntp/build/classes
/home/thufir/NetBeansProjects/nntp/src/net/bounceme/dur/misc/StaticRef.java:11: non-static variable f cannot be referenced from a static context
        f.connect();  //move this to inside "run"
1 error
/home/thufir/NetBeansProjects/nntp/nbproject/build-impl.xml:626: The following error occurred while executing this line:
/home/thufir/NetBeansProjects/nntp/nbproject/build-impl.xml:245: Compile failed; see the compiler error output for details.
BUILD FAILED (total time: 0 seconds)

然而,到目前为止我找不到任何东西。我在线程示例中看到类似的东西,但无法完全获得语法。

以下是我想要的,但我不认为这是正确的:

package net.bounceme.dur.misc;

public class StaticRef {

    Foo f = Foo.INSTANCE;

    public static void main(String[] args) throws Exception {

        StaticRef sf = new StaticRef();
        sf.f.connect();
    }
}

我想要的是将sf的实例化为...我不太确定。也许以上是正确的并且“好”?

5 个答案:

答案 0 :(得分:1)

你有一些选择:

  • Foo移至main
  • 的范围内
  • Foo声明为静态变量

    static Foo f = Foo.INSTANCE;
    
  • 创建StaticRef的实例并使用该

    中的对象
    new StaticRef().f.connect();
    

答案 1 :(得分:1)

无法从静态上下文引用您的实例变量。 你需要一个类的对象来获取(引用)它的内容。

您可以编写单例模式:

public class SingletonDemo {
    private static SingletonDemo instance = null;

    private SingletonDemo() {       }

    public static SingletonDemo getInstance() {
            if (instance == null) {
                instance = new SingletonDemo ();
            }
            return instance;
    }

}

如果线程安全是个问题,您可以使用枚举:

public enum Singleton{
    INSTANCE;
    private Singleton(){ ... }
}

public class Singleton{
    private final static Singleton instance = new Singleton();
    private Singleton(){ ... }
    public static Singleton getInstance(){ return instance; }
}

请参阅here

答案 2 :(得分:1)

很抱歉,无法发表评论所以我必须将其作为答案发布。

更新的代码很好,但由于Foo.INSTANCE似乎是Singleton pattern的使用,因此将其定义为静态并在第一个示例中使用它是有意义的。最多只有一个Foo.INSTANCE值,因此使StaticRef的每个实例都有自己对Foo.INSTANCE的引用是没有意义的。

答案 3 :(得分:0)

如果此代码“有缺陷”或违反任何OOP原则,请进行评论:

package net.bounceme.dur.misc;

public class StaticRef {

    private Foo f = Foo.INSTANCE;

    public StaticRef() throws Exception {
        f.connect();
    }

    public static void main(String[] args) throws Exception {
        new StaticRef();
    }
}

我听说过这种方法的理由是,为了重复使用,可以通过简单地删除main方法来轻松修改StaticRef以充当Java Bean。请做评论。 See also this answer, for a similar solutionthis other answer

答案 4 :(得分:-1)

java规则

您无法访问静态方法中的非静态变量

检查日志,然后您就知道问题了。