Java Anonymous inner class

In Java, an anonymous inner class is a local inner class that is defined and instantiated in a single expression. Anonymous inner classes are often used when we need to define a class that will be used only once and don’t want to create a separate file for it.

Anonymous inner classes are declared using the syntax:

new SuperType(constructor parameters) {
  // class body
}

Here, SuperType is the class or interface being extended or implemented by the anonymous inner class. The body of the anonymous inner class follows the same syntax as a regular class or interface definition.

For example, consider the following code that defines an anonymous inner class that implements the Runnable interface:

Thread t = new Thread(new Runnable() {
  public void run() {
    System.out.println("Hello, world!");
  }
});
t.start();

Here, we are creating a new Thread object and passing an anonymous inner class that implements the Runnable interface as an argument to its constructor. The run() method of the Runnable interface is defined within the anonymous inner class, and when the thread is started, it will execute the run() method and print “Hello, world!” to the console.

Anonymous inner classes can also access variables in their enclosing scope, but these variables must be declared final or effectively final to be used within the anonymous inner class. This is because the variables are passed by value to the anonymous inner class and must be immutable to ensure their values don’t change between the time the inner class is created and the time it is executed.

Java anonymous inner class example using class:

Sure, here is an example of using an anonymous inner class in Java to define a new class that extends an existing class:

public class AnonymousInnerClassExample {
  public static void main(String[] args) {
    // create an instance of the anonymous class that extends the Person class
    Person p = new Person("John") {
      @Override
      public void sayHello() {
        System.out.println("Hello, my name is " + getName());
      }
    };

    // call the sayHello method of the anonymous class
    p.sayHello();
  }
}

class Person {
  private String name;

  public Person(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void sayHello() {
    System.out.println("Hello, my name is " + name);
  }
}

In this example, we define an anonymous inner class that extends the Person class and overrides its sayHello method to print a customized greeting that includes the person’s name. We create an instance of the anonymous inner class and call its sayHello method to print the greeting.

Note that the anonymous inner class is declared and instantiated in a single expression using the following syntax:

new Person("John") {
  @Override
  public void sayHello() {
    System.out.println("Hello, my name is " + getName());
  }
}

Here, we are creating a new instance of the Person class with a name of “John”, but we are also defining a new class that extends the Person class and overrides its sayHello method. This new class is defined within the curly braces after the new Person("John") expression, and we use the @Override annotation to indicate that we are overriding a method from the superclass.

When we call the sayHello method on the instance of the anonymous inner class, it will print the customized greeting that we defined within the anonymous class.

Internal working of given code:

Sure, let me explain how the given code works:

Thread t = new Thread(new Runnable() {
  public void run() {
    System.out.println("Hello, world!");
  }
});
t.start();

This code creates a new Thread object and passes an anonymous inner class that implements the Runnable interface as a parameter to its constructor.

The anonymous inner class is defined as:

new Runnable() {
  public void run() {
    System.out.println("Hello, world!");
  }
}

Here, we are creating a new instance of the Runnable interface and defining its run method within the anonymous inner class. When the thread is started, it will execute the run method defined within the anonymous inner class, which simply prints “Hello, world!” to the console.

The t.start() method call starts the thread, which causes the run method of the anonymous inner class to be executed in a separate thread of control.

The reason for using an anonymous inner class in this case is to define the run method of the Runnable interface without having to create a separate named class for it. Since the run method is the only method defined by the Runnable interface, it is often more concise to use an anonymous inner class instead of creating a separate named class that implements the interface.

I hope this explanation helps!

Internal class generated by the compiler:

When we define an anonymous inner class in Java, the compiler generates a new class file for the anonymous class with a generated name that is typically composed of the outer class name, a dollar sign, and a sequential number.

For example, consider the following code:

public class Outer {
  public void foo() {
    Bar bar = new Bar() {
      public void baz() {
        System.out.println("Hello, world!");
      }
    };
    bar.baz();
  }
}

interface Bar {
  void baz();
}

In this code, we define an anonymous inner class that implements the Bar interface and overrides its baz method. When the foo method of the Outer class is called, it creates an instance of the anonymous inner class and calls its baz method.

The compiler will generate a new class file for the anonymous inner class with a name like Outer$1.class. This class file will contain the implementation of the anonymous inner class and will be loaded by the JVM at runtime when the class is used.

The generated class file will have access to the members of the outer class, including private members, because it is an inner class of the outer class. However, the generated class file will not have a reference to the this object of the outer class. Instead, it will have a reference to a synthetic field in the outer class that holds a reference to the outer class instance.

It is important to note that the generated class file for an anonymous inner class is not named or declared explicitly in the source code and is not accessible from other classes, making it effectively “invisible” to the rest of the program.

Java anonymous inner class example using interface:

Sure, here is an example of using an anonymous inner class in Java to implement an interface:

public class AnonymousInnerClassExample {
  public static void main(String[] args) {
    // create an instance of the anonymous class that implements the MyInterface interface
    MyInterface obj = new MyInterface() {
      @Override
      public void doSomething() {
        System.out.println("Doing something...");
      }
    };

    // call the doSomething method of the anonymous class
    obj.doSomething();
  }
}

interface MyInterface {
  void doSomething();
}

In this example, we define an anonymous inner class that implements the MyInterface interface and overrides its doSomething method to print a message to the console. We create an instance of the anonymous inner class and call its doSomething method to perform the action.

Note that the anonymous inner class is declared and instantiated in a single expression using the following syntax:

new MyInterface() {
  @Override
  public void doSomething() {
    System.out.println("Doing something...");
  }
}

Here, we are creating a new instance of the MyInterface interface, but we are also defining a new class that implements the MyInterface interface and overrides its doSomething method. This new class is defined within the curly braces after the new MyInterface() expression, and we use the @Override annotation to indicate that we are overriding a method from the interface.

When we call the doSomething method on the instance of the anonymous inner class, it will print the message that we defined within the anonymous class.