4
abstract class Person {  
abstract void eat();  
}  

class TestAnonymousInner {  
  public static void main(String args[]){  
  Person p=new Person() {  
    void eat(){System.out.println("nice fruits");}  
    };  
  p.eat();  
  }  
}

Internal class generated by the compiler

static class TestAnonymousInner$1 extends Person
{
    TestAnonymousInner$1(){}
    void eat()
    {
        System.out.println("nice fruits");
    }
}

For which reason does the compiler create the anonymous class as static? What would happen if it's non-static?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Rohan Patel
  • 1,758
  • 2
  • 21
  • 38

1 Answers1

8

The code as shown creates an anonymous class in a static context. An inner class (or non-static nested class) needs to have a reference to the enclosing object(*). In this case there is no enclosing object because it is created in a static method, so using a static nested class is the only valid option.

This can easily be demonstrated by transforming your example to

public class TestInner {
    public static void main(String args[]){
        Person p = new Testperson();
        p.eat();
    }

    public class Testperson extends Person {
        void eat() {
            System.out.println("nice fruits");
        }
    }
}

Compiling this will yield the error

non-static variable this cannot be referenced from a static context

While it will compile just fine if you change it to:

public class TestInner {
    public static void main(String args[]){
        Person p = new Testperson();
        p.eat();
    }

    public static class Testperson extends Person {
        void eat() {
            System.out.println("nice fruits");
        }
    }
}

*: The compiler will modify the constructor(s) of an inner class to accept the enclosing object as a parameter, and constructor calls will be rewritten to pass this as the value of that parameter. This is not the case for static nested classes.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197