简体   繁体   中英

reference an instance variable from a static method java

Line 1:  public class C { 
Line 2:      public static void main(String[] args) { 
Line 3:         // method2();
Line 4:      }
Line 5: 
Line 6:      
Line 7:      Circle c = new Circle();
Line 8:      public static void method2() { 
Line 9:          // Circle c = new Circle();
Line 10: 
Line 11:        System.out.println("What is radius "+ c.getRadius()); //compile error : non-static variable c cannot be referenced from a static context.  Why? here "c" is a instance variable. 
Line 12:     }
Line 13: 
Line 14:    
Line 15:  }
Line 16:  
Line 17:   class Circle
Line 18:  {
Line 19:    public  int getRadius()
Line 20:    {
Line 21:        return 3;
Line 22:    }
Line 23:  }

Question : in line 11 ,compile error says, non-static variable c cannot be referenced from a static context. Why? here "c" is a instance variable. But the following code is ok . Why?

if I change From line 8 to 12

public static void method2() { 
    Circle c = new Circle();
    System.out.println("What is radius "+ c.getRadius()); 
}

Or:

Circle c = new Circle();
public void method2() { 
    System.out.println("What is radius "+ c.getRadius());
}

When you create a method with the static keyword, it is a static method, or a class method. This means that it is the same for every instance of the object, so you cannot access an instance variable from inside it. From inside static methods you can only access static variables or call static methods of the class.

Creating instance inside the static method and outside the method is different.

While you are accessing them in static methods , either the variables,references must be static or they must be local to that static method.

case 1

When you define Circle c = new Circle(); outside a method, that becomes an instance member and you can't access that in static method.

case2 :

public static void method2() { 
    Circle c = new Circle();
    System.out.println("What is radius "+ c.getRadius()); 
}

Here in this case c is local to that method and instance member never comes into picture.Everything is local to this method.

Moral: You can't access Instance members in static methods.

The static members can be used without an instance of the class, but your c variable will only start to exist once the class is instantiated. The compiler 'll check whether your code 'can' run, and before instantiation, the static method can be called, but that c instance not.

The second block is ok, since there method2 is an instance method, where as in the first attempt, method2 is still static.

Other solutions are: make ca static variable, or make it a local variable within method2.

From the documentation :

Not all combinations of instance and class variables and methods are allowed:

- Instance methods can access instance variables and instance methods
  directly.
- Instance methods can access class variables and class methods
  directly.
- Class methods can access class variables and class methods directly.
- Class methods cannot access instance variables or instance methods
  directly—they must use an object reference. Also, class methods
  cannot use the this keyword as there is no instance for this to refer to.

Based on the above:

  • Your original code has a class method trying to access an instance variable which is not allowed.
  • In the first example from your changed code, you declare the variable c within the static method, so that the variable is accessible throughout that method.
  • In the second changed example, the method is an instance method, trying to access an instance variable, which is also allowed.

In your first example Circle c is a member variable. You create an instance of this class when an instance of your class C is created. When you call the method in your static method there is no instance of Circle c .

Your 2nd example works cause you create the instance in your method and call it in there.

Your 3rd example works because it is a member variabel and a member method so java can be sure the is an instance of Circle c before your method2() is called.

I hope I could help.

In the OP there seems to be some confusion over the meaning of static.

A static function is a function which is available in the absence of any enclosing instance. This means that it can be invoked according to the syntax Class.function. A non static function requires you to create an instance of an object

Object instance = using new Object{}
instance.method()

In order for this to be the case, it is a necessary condition that a static function should be stateless. That is to say, that the only variables accesses are either scoped to the function, or are method parameters, or are static members of the enclosing class. Thus it is forbidden for a static method to attempt to change any non static member of its enclosing class.

So:

public class Demo{
    public static int staticCounter = 0;
    public int instanceCounter = 0;

    public static int getStaticCounter(){
        return staticCounter++;
    }

    public int getInstanceCounter(){
        staticCounter++;
        return instanceCounter++;
    }
}

So I can call these functions from the following code@

public class widget{
    public static void main(String arg[]){
        System.out.println(demo.getStaticCounter()); // returns zero 
        //Node that I can access the static method before creating any object;
        Demo widget = new Demo();
        System.out.println(widget.getInstanceCounter()); //returns zero
        System.out.println(widget.getInstanceCounter()); //returns one


        System.out.println(widget.getStaticCounter()); // returns 2.
        // note that its generally considered bad practice to call a static method via an instance. Call Demo.getStaticCOunter() instead.

        Demo anotherWidget = new Demo();
        System.out.println(anotherWidget.getInstanceCounter()); //returns zero
        System.out.println(anotherWidget.getInstanceCounter()); //returns one
        //since these get a new copy of the instance variable...
        System.out.println(Demo.getStaticCounter()); // returns 5.
        //but share their static variable.
    }
}

您正在使用实例方法,因此您需要该类的对象来访问它。只有当您拥有该类的对象时,您才能访问实例方法(如果方法或变量中没有 static 关键字,则为实例方法或变量)但对于静态方法,您不需要创建该类的对象。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM