Reader small image

You're reading from  Java Coding Problems - Second Edition

Product typeBook
Published inMar 2024
PublisherPackt
ISBN-139781837633944
Edition2nd Edition
Right arrow
Author (1)
Anghel Leonard
Anghel Leonard
author image
Anghel Leonard

Anghel Leonard is a Chief Technology Strategist and independent consultant with 20+ years of experience in the Java ecosystem. In daily work, he is focused on architecting and developing Java distributed applications that empower robust architectures, clean code, and high-performance. Also passionate about coaching, mentoring and technical leadership. He is the author of several books, videos and dozens of articles related to Java technologies.
Read more about Anghel Leonard

Right arrow

46. Adding nested classes in anonymous classes

In the previous problem, we had a brief overview of nested classes. As a quick reminder, an anonymous class (or, anonymous inner class) is like a local inner class without a name. Their purpose is to provide a more concise and expressive code. However, the code readability may be affected (look ugly), but it may be worth it if you can perform some specific task without having to do a full-blown class. For instance, an anonymous class is useful for altering the behavior of an existing method without spinning a new class. Java uses them typically for event handling and listeners (in GUI applications). Probably the most famous example of an anonymous class is this one from Java code:

button.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    ...
  }
}

Nevertheless, while local inner classes are actually class declarations, anonymous classes are expressions. To create an anonymous class, we have to extend an existing class or implement an interface, as shown in the following figure:

Figure 2.28.png

Figure 2.29: Anonymous class via class extension and interface implementation

Because they don’t have names, anonymous classes must be declared and instantiated in a single expression. The resulting instance can be assigned to a variable that can be referred to later. The standard syntax for expressions looks like calling a regular Java constructor having the class in a code block ending with a semi-colon (;). The presence of a semi-colon is a hint that an anonymous class is an expression that must be part of a statement.

Finally, anonymous classes cannot have explicit constructors, be abstract, have a single instance, implement multiple interfaces, or be extended.

Next, let’s tackle a few examples of nesting classes in anonymous classes. For instance, let’s consider the following interface of a printing service:

public interface Printer {
    public void print(String quality);
}

We use the Printer interface all over the place in our printing service, but we also want to have a helper method that is compact and simply tests our printer functions without requiring further actions or an extra class. We decided to hide this code in a static method named printerTest(), as follows:

public static void printerTest() {
  Printer printer = new Printer() {
  @Override
  public void print(String quality) {
    if ("best".equals(quality)) {
      Tools tools = new Tools();
      tools.enableLaserGuidance();
      tools.setHighResolution();
    }
    System.out.println("Printing photo-test ...");
  }
class Tools {
    private void enableLaserGuidance() {
      System.out.println("Adding laser guidance ...");
    }
    private void setHighResolution() {
      System.out.println("Set high resolution ...");
    }
  }
};

Testing the best quality print requires some extra settings wrapped in the inner Tools class. As you can see, the inner Tools class is nested in the anonymous class. Another approach consists of moving the Tools class inside the print() method. So, Tools becomes a local inner class as follows:

Printer printer = new Printer() {
  @Override
  public void print(String quality) {
    class Tools {
      private void enableLaserGuidance() {
        System.out.println("Adding laser guidance ...");
      }
      private void setHighResolution() {
        System.out.println("Set high resolution ...");
      }
    }
    if ("best".equals(quality)) {
      Tools tools = new Tools();
      tools.enableLaserGuidance();
      tools.setHighResolution();
    }
    System.out.println("Printing photo-test ...");
  }
};

The problem with this approach is that the Tools class cannot be used outside of print(). So, this strict encapsulation will restrict us from adding a new method (next to print()) that also needs the Tools class.

JDK 16+

But, remember from the previous problem that, starting with JDK 16, Java inner classes can have static members and static initializers. This means that we can drop the Tools class and rely on two static methods as follows:

Printer printer = new Printer() {
  @Override
  public void print(String quality) {
    if ("best".equals(quality)) {
      enableLaserGuidance();
      setHighResolution();
    }
    System.out.println("Printing your photos ...");
  }
  private static void enableLaserGuidance() {
    System.out.println("Adding laser guidance ...");
  }
  private static void setHighResolution() {
    System.out.println("Set high resolution ...");
  }
};

If you find it more convenient to pick up these helpers in a static class, then do it:

Printer printer = new Printer() {
  @Override
  public void print(String quality) {
    if ("best".equals(quality)) {
      Tools.enableLaserGuidance();
      Tools.setHighResolution();
    }
    System.out.println("Printing photo-test ...");
  }
  private final static class Tools {
    private static void enableLaserGuidance() {
      System.out.println("Adding laser guidance ...");
    }
    private static void setHighResolution() {
      System.out.println("Set high resolution ...");
    }
  }
};

You can practice these examples in the bundled code.

Previous PageNext Page
You have been reading a chapter from
Java Coding Problems - Second Edition
Published in: Mar 2024Publisher: PacktISBN-13: 9781837633944
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Anghel Leonard

Anghel Leonard is a Chief Technology Strategist and independent consultant with 20+ years of experience in the Java ecosystem. In daily work, he is focused on architecting and developing Java distributed applications that empower robust architectures, clean code, and high-performance. Also passionate about coaching, mentoring and technical leadership. He is the author of several books, videos and dozens of articles related to Java technologies.
Read more about Anghel Leonard