what is the work-around to “non-static variable ca

2019-06-14 16:26发布

问题:

There's a particular idiom to putting a method, or perhaps anonymous inner class, somehow, into the main method of a driver class:

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
        }
         */
    }
}

to prevent the below error:

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)

However, I can't find anything so far. I see something similar in threading examples, but can't quite get the syntax.

The following is largely what I want, but I don't think it's quite correct:

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();
    }
}

What I would like is to put the instantiation of sf into...I'm not quite sure. Maybe the above is correct and "ok"?

回答1:

You have some options:

  • Move Foo into the scope of main
  • Declare Foo as a static variable

    static Foo f = Foo.INSTANCE;
    
  • Create an instance of StaticRef and use the object from that

    new StaticRef().f.connect();
    


回答2:

Sorry, can't comment yet so I have to post it as an answer.

The updated code is fine, but since Foo.INSTANCE seems to be a use of the Singleton pattern, it makes sense to define it as static and use it as in your first example. At most there will be a single value of Foo.INSTANCE, so it doesn't make sense to make each instance of StaticRef to have its own reference to Foo.INSTANCE.



回答3:

Your instance variable cannot be referenced from a static context. You need an object of the class to get (a reference to) it's contents.

You can write a Singleton pattern:

public class SingletonDemo {
    private static SingletonDemo instance = null;

    private SingletonDemo() {       }

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

}

If thread safety is an issue, you can use an enum:

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

or

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

See here



回答4:

If this code is "faulty" or violates any OOP principle, please do comment:

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();
    }
}

The justification I've heard for this approach is that, for re-use, StaticRef can be easily modified to act as a Java Bean by doing little more than removing the main method. Please do comment. See also this answer, for a similar solution, or this other answer.



回答5:

java rule

You Cannot access non static variable inside a static method

Check the log then you know the problem.