Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is an anonymous class in a static context valid

I have a misunderstanding about what an anonymous class in Java is. Consider the following simple example:

public static void main (String[] args) throws java.lang.Exception
{
    B b = new B(){ };
    System.out.println(b.b);
}

interface B{ int b = 1; }

DEMO

Why does the code compile? The JLS, chapt 15 says:

An anonymous class is always an inner class (§8.1.3); it is never static

But the JLS, chapt 8

An inner class is a nested class that is not explicitly or implicitly declared static.

So the anonymous class is an inner class. But we use them in the static context. Why is it correct here?

like image 586
St.Antario Avatar asked Jan 02 '15 07:01

St.Antario


2 Answers

A class can be created in a static context without being declared static, and this is what is happening here. Let's look at what being declared static, and created in a static context means:

The difference between an anonymous class created in a static context and a non-static context is whether it has an enclosing instance:

If C is an anonymous class, then:

  • If the class instance creation expression occurs in a static context, then i has no immediately enclosing instance.

  • Otherwise, the immediately enclosing instance of i is this.

A nested class that is declared static allows static members:

An inner class is a nested class that is not explicitly or implicitly declared static.

A nested class that is not an inner class may declare static members freely, in accordance with the usual rules of the Java programming language.

By saying a nested class that is 'implicity declared static', it refers to things like classes within interfaces:

A member class of an interface is implicitly static (§9.5) so is never considered to be an inner class.

Anonymous classes are not declared static (neither explicitly with a keyword, or implicitly such as being inside an interface), and so do not allow the declaration of static members. They can however be created within a static context, which means that they don't refer to an enclosing instance.

Because the anonymous classes are not declared static, both quotes in the question are consistent.

like image 50
fgb Avatar answered Oct 25 '22 13:10

fgb


You should differentiate between anonymous and inner classes

With this statement you create a class implementing the interface B. The class has no name so it's called an anonymous class. The javac compile will create a class file with following naming rule YourClass$1.class (where 1 is a sequential number, based on the number of anonymous classes in YourClass.

B b = new B(){ };

The class created by new B(){ } cannot be declared as static. ("An anonymous class is always an inner class (§8.1.3); it is never static").

A static nested class example

class YourClass {
    static class StaticNestedClass {
    }
}

A non-static nested class example

class YourClass {
    // An inner class is a nested class that is not explicitly or implicitly declared static.
    class InnerClass {
    }
}

There are two types of nested classes: static and non-static. Nested classes which are declared static are so-called static nested classes, whereas nested classes not declared as static are so-called inner classes.

like image 24
SubOptimal Avatar answered Oct 25 '22 13:10

SubOptimal