Java - Anonymous class are static or not

2019-07-17 04:18发布

问题:

I know it depends on the context in which the anonymous class has been written (static or non static method). but look this part of code:

public class A {
    int fieldOfA;

    private static class B {
        int fieldOfB;
    }

    public static void main(String[] args) {

        B obj = new B() { //this anonymous class is static becuase is in the main method.

            private static void testMethod() { //so why here i have an error and i can put just a non-static method
                                               //if my class is static ?
                                               //a class static can have static method, but this class no, why?
            }
        };
    }
}

it's sure that anonymous class are static?

回答1:

An anonymous class is static if the context is static. e.g. in a static method.

An anonymous class is non static if there is a non static context, whether you need it to be non-static or not. The compiler is not smart enough to make a class static if the non static context is not used.

In this example, two anonymous classes were created. One in a static method has no reference to an outer class and is like a static nested class.

Note: these classes are still called "Inner" and cannot have static members even though they have no reference to an Outer class.

import java.util.Arrays;

public class Main {
    Object o = new Object() {
        {
            Object m = Main.this; // o has a reference to an outer class.
        }
    };

    static Object O = new Object() {
        // no reference to Main.this;
        // doesn't compile if you use Math.this
    };

    public void nonStaticMethod() {
        Object o = new Object() {
            {
                Object m = Main.this; // o has a reference to an outer class.
            }
        };
        printFields("Anonymous class in nonStaticMethod", o);
    }

    public static void staticMethod() {
        Object o = new Object() {
            // no reference to Main.this;
            // doesn't compile if you use Math.this
        };
        printFields("Anonymous class in staticMethod", o);
    }

    private static void printFields(String s, Object o) {
        System.out.println(s + " has fields " + Arrays.toString(o.getClass().getDeclaredFields()));
    }

    public static void main(String... ignored) {
        printFields("Non static field ", new Main().o);
        printFields("static field ", Main.O);
        new Main().nonStaticMethod();
        Main.staticMethod();
    }
}

prints

Non static field  has fields [final Main Main$1.this$0]
static field  has fields []
Anonymous class in nonStaticMethod has fields [final Main Main$3.this$0]
Anonymous class in staticMethod has fields []


回答2:

From JLS 15.9.5:

An anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.1).

Section 8.1.3 talks more about inner classes, including when they occur in a static context. But they're never static themselves, and thus can't declare static members (other than constant variables).