Home > Software engineering >  <<Cannot make a static reference to the non-static field>> has diff meanings?
<<Cannot make a static reference to the non-static field>> has diff meanings?

Time:11-28

may be am unable to understand, but check below code

In warning code line, why its just a warning ?

In Error line code, why its not giving just a warning ?

public class Rnd {

    public AppName appName;
    static String staticField = "static";

    public AppName getApp(String appName) {

        return () -> appName;
    }

    public static void main(String[] args) {

        Rnd o = new Rnd();
        System.out.println(o.staticField); // why just a warning ? <<The static field Rnd.staticField should be accessed in a static way>>
                                                 
        appName = o.getApp("myApp"); // why compile error ? <<Cannot make a static reference to the non-static field appName>>
                                            
        System.out.println(o.appName);

    }

}

calling from non static ref to static ref, is only issue or accessing non static ref to non static ref from static space (method) is also an issue ?

CodePudding user response:

"The static field Rnd.staticField should be accessed in a static way" is a warning (not an error) because the Java syntax allows it and the code works.

"The static field Rnd.staticField should be accessed in a static way" is a warning because not accessing it in a static way makes the code harder to understand, harder to change and can lead to surprising bugs.

Consider this sample code:

public class Static {
    static String f1 = "aaa";
    String f2 = "bbb";

    public static void main(String[] args) {
        Static a = new Static();
        Static b = new Static();
        System.out.printf("a: f1=%s f2=%s%n", a.f1, a.f2);
        System.out.printf("b: f1=%s f2=%s%n", b.f1, b.f2);
        a.f1 = "new Field1";
        a.f2 = "new Field2";
        System.out.printf("a: f1=%s f2=%s%n", a.f1, a.f2);
        System.out.printf("b: f1=%s f2=%s%n", b.f1, b.f2);
    }
}

Changing the field "a.f1" seems to change the field "b.f1" too. This is because there are no fields a.f1 and b.f1, there is only one field Static.f1.

In this sample code the definition of the field f1 and the usage is sufficiently near to see the problem. But consider the case where the definition of such a field is in a different package from the usage and looking up how the field is actually defined requires to switch between class definition and class usage.

CodePudding user response:

In Java, at runtime, a class is basically two things:

  1. A definition
  2. An "instance" of all static members contained in the definition

Your class has 2 static members:

static String staticField = "static";
public static void main(String[] args)

It also has 2 non-static members i.e. members that only exist in class instances:

public AppName appName;
public AppName getApp(String appName)

In your main you create a new instance of Rnd and that instance has members appName and getApp and you attempt to access o.staticField from that. Java will warn you that you are accessing a static field from a non-static context but it is able to do that since in this case there's no ambiguity. The static members are always defined as part of the permanent singleton static "instance" of the class.

The problem arises when you try to assign values to a non-static field from a static context. Remember that your main is static so the line:

appName = o.getApp("myApp"); 

is doing exactly that. The context is static and appName is not static so this cannot work.

To fix it you need to do:

o.appName = o.getApp("myApp");

Note that I am assuming that AppName is defined somewhere else and is correct

  •  Tags:  
  • java
  • Related