71

I came across this code today whilst reading Accelerated GWT (Gupta) - page 151.

public static void getListOfBooks(String category, BookStore bookStore) {
    serviceInstance.getBooks(category, bookStore.new BookListUpdaterCallback());
}
public static void storeOrder(List books, String userName, BookStore bookStore) {
    serviceInstance.storeOrder(books, userName,    bookStore.new StoreOrderCallback());
}

What are those new operators doing there? I've never seen such syntax, can anyone explain?

Does anyone know where to find this in the java spec?

chickeninabiscuit
  • 9,061
  • 12
  • 50
  • 56

3 Answers3

67

They're inner (nested non-static) classes:

public class Outer {
  public class Inner { public void foo() { ... } }
}

You can do:

Outer outer = new Outer();
outer.new Inner().foo();

or simply:

new Outer().new Inner().foo();

The reason for this is that Inner has a reference to a specific instance of the outer class. Let me give you a more detailed example of this:

public class Outer {
  private final String message;

  Outer(String message) {
    this.message = message;
  }

  public class Inner {
    private final String message;

    public Inner(String message) {
       this.message = message;
    }

    public void foo() {
      System.out.printf("%s %s%n", Outer.this.message, message);
    }
  }
}

and run:

new Outer("Hello").new Inner("World").foo();

Outputs:

Hello World

Note: nested classes can be static too. If so, they have no implicit this reference to the outer class:

public class Outer {
  public static class Nested {
    public void foo() { System.out.println("Foo"); }
  }
}

new Outer.Nested.foo();

More often than not, static nested classes are private as they tend to be implementation details and a neat way of encapsulating part of a problem without polluting the public namespace.

Bloke
  • 2,229
  • 3
  • 22
  • 27
cletus
  • 616,129
  • 168
  • 910
  • 942
  • 1
    It's all spelled out here if anyone's hazy on this: http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html – chickeninabiscuit May 19 '10 at 06:19
  • and also a good discussion here: http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class – chickeninabiscuit May 19 '10 at 06:21
  • 1
    @cleutus "More often than not, static inner classes are private" . This is a wrong statement . inner classes can't be static . This should be called as "static nested class". See the link http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class – Inquisitive Jul 02 '12 at 11:32
  • shouldn't the last code line read `new Outer.Nested().foo();`? – AplusKminus Aug 03 '16 at 10:08
  • In my experience, the last paragraph is backwards; inner classes are often private (because they're implementing some interface like `Iterator` that needs privileged access to the top-level class), and static nested classes are data types like command objects or exceptions that apply to one specific context. – chrylis -cautiouslyoptimistic- Jan 07 '19 at 05:44
4

BookListUpdaterCallback and StoreOrderCallback are inner classes of BookStore.

See The Java Tutorial - http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html and http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html

Greg Case
  • 46,881
  • 3
  • 27
  • 21
1

I haven't seen this syntax before either, but I think it will create an inner class of BookStore.

tangens
  • 39,095
  • 19
  • 120
  • 139