Blakes 21 Days Chapter 16 Document
Day 16, Using Inner Classes and Closures
- Top
- 449 Each new version of the Java language takes it further from its humble origins in 1995.
- When it was first released, Java had only 250 classes in the Java Class Library and was primarily used to put interactive programs on Web pages.
- These applets, as they were dubbed, brought something new to the Web and inspired several hundred thousand programmers to learn the new language.
- 449 Because the language was well-designed and offered some features that made it a worthy rival to C++ and other choices for software development,
- Java quickly outgrew its original focus to become a general-purpose programming language.
- Today it is the most widely implemented, popular language in the world.
- 449 There are millions of Java coders today putting its classes on several billion devices as the language turns 20.
- Each new release embraces new capabilities that bring sophisticated new methodologies to Java that are eagerly anticipated by programmers.
- 449 Java 8 offers a new feature that may be the most requested ever: closures.
- 449 Closures, also called lambda expressions, make it possible in Java to employ a methodology called functional programming.
- 449 Today you will learn about closures after an introduction to their use: inner classes and anonymous inner classes.
Inner Classes
- Top
- 450 When you create a class in Java, you must define its attributes and behavior.
- The attributes are the class and instance variables that hold data, and the behavior is the methods that use that data to perform tasks.
- 450 A class also can contain a third element that combines both attributes and behavior, an inner class.
- 450 Inner classes are like helper classes, but they are defined inside the class they were created to help.
- Because a Java program can have as many classes as you think are necessary, you might be questioning the point of inner classes.
- A Scheduler class that manages work schedules at your resturant
- could have an Employee helper class for each worker and a Day helper class for each weekday the business is open.
- 450 Through some of the purpose of an inner class can be accomplished with a helper class,
- as you learn more about them you will encounter situations where they're better suited to a particular project.
- Top
- 450 Java includes inner classes for several reasons.
- 450 If a class is used by only one other class, it's a good idea to define it inside that class.
- That keeps the code in one place and makes clear the relationship between the classes.
- 450 An inner class can access private methods and variables of its enclosing class that a helper class could not access.
- This is possible for the same reason that a method in a class cann access private variables of that class.
- 450 NOTE: Rules governing the scope of an inner class closely match those governing variables.
- An inner class's name is not visible outside its scope,
- except in a fully qualified name (the enclosing class name followed by a period and inner class name).
- This helps in structuring classes within a package.
- The code for an inner class can use simple names from enclosing scopes,
- including class and member variables of enclosing classes, as well as local variables of enclosing blocks.
- 450 To create an inner class, use the class keyword and a class declaration like any other class, but place it inside the containing class.
- An inner class usually is put in the same place that class and instance variables are defined.
- Top
- 451 Here's an inner class called InnerHello in a class called Hello:
public class Hello {
class InnerHello {
InnerHello() {
System.out.println(
"The method call is coming from inside theclass!"
);
}
}
public Hello() {
// empty constructor
}
public static void main(String[] arguments) {
Hello program = new Hello();
Hello.InnerHello inner = program.new InnerHello();
}
}
- Top
- 451 The inner class is defined just like any other class, except for its position:
- It is placed within the { and } brackets of another class.
- 451 Creating an object of an inner class requires an object of the outer class.
- The new operator is called on the object, as in this statement from the preceding example:
- Hello.InnerHello inner = program.new InnerHello();
- Top
- 451 Look at both halves of this assignment statement to learn how the object of the inner class is created.
- 451 On the left, the name of the inner class consists of the name of the outer class,
- a period character (".") and the inner class name.
- So Hello.InnerHello is the name.
- 451 On the right, program refers to the Hello object.
- The reference to program is followed by a period, the new operator, and the inner class constructor InnerHello().
First Program - Listing 16.1
- Top
- 451 The day's first project rewrites the ComicBook application from Day 8, "Data Structures," to use an inner class.
- That project managed a comic book collection with a main class called ComicBooks and a helper class called Comic for each comic in a collection.
- Both were defined in the same source code file, but as separate classes.
- The compiler turned them into the bytecode files ComicBooks.class and Comic.class.
- 451 This time around, there's a ComicBox class for the collection and an InnerComic inner class.
- Top
- 452 The ComicBox application is shown in Listing 16.1.
- Create a new empty Java file in the com.java21days package for this project called ComicBox.java.
Listing 16.1 - The Full Text of ComicBox.java
- Top
- page 452 - 453
package com.java21days;
import java.util.*;
public class ComicBox {
class InnerComic {
String title;
String issueNumber;
String condition;
float basePrice;
float price;
InnerComic(String inTitle, String inIssueNumber,
String inCondition, float inBasePrice) {
title = inTitle;
issueNumber = inIssueNumber;
condition = inCondition;
basePrice = inBasePrice;
}
void setPrice(float factor) {
price = basePrice * factor;
}
}
public ComicBox() {
HashMap<String, Float> quality = new HashMap<>();
float price1 = 3.00F;
quality.put("mint", price1);
float price2 = 2.00F;
quality.put("near mint", price2);
float price3 = 1.50F;
quality.put("very fine", price3);
float price4 = 1.00F;
quality.put("fine", price4);
float price5 = 0.50F;
quality.put("good", price5);
float price6 = 0.25F;
quality.put("poor", price6);
InnerComic[] comix = new InnerComic[3];
comix[0] = new InnerComic("Amazing Spider-Man", "1A",
"very fine",12_000.00F);
comix[0].setPrice(quality.get(comix[0].condition));
comix[1] = new InnerComic("Incredible Hulk", "181",
"near mint", 680.00F);
comix[1].setPrice(quality.get(comix[1].condition));
comix[2] = new InnerComic("Cerebus", "1A", "good", 190.00F);
comix[2].setPrice(quality.get(comix[2].condition));
for (InnerComic comix1 : comix) {
System.out.println("Title: " + comix1.title);
System.out.println("Issue: " + comix1.issueNumber);
System.out.println("Condition: " + comix1.condition);
System.out.println("Price: $" + comix1.price + "\n");
}
}
public static void main(String[] arguments) {
new ComicBox();
}
}
The Explanation
- Top
- 453 The inner class, which is defined in Lines 6 - 25, has a constructor that creates a comic book using title, issue number, condition, and base price.
- There's also a setPrice() method in Lines 22 - 24.
- 453 The ComicBox class uses this inner class in Line 41, creating an array that holds three InnerComic objects.
- The inner class is referred to as InnerComic, the same as if it was a helper class.
- 453 You also could have referred to the inner class using its full name, which includes the name of its enclosing class:
ComicBox.InnerComic[] comix = new ComicBox.InnerComic[3];
- 453 The output of the application is displayed in Figure 16.1
Figure 16.1 - Using inner classes to collect comic books. - goes here
Anonymous Inner Classes
- Top
- 454 Often in Java programming you need to create an object in one statement that never will be referred to again.
- There's a special type of inner class well-suited to this purpose: an anonymous inner class.
- This is a class that has no name and is declared and created in the same statement.
- 454 To use an anonymous inner class,
- you take a place where you'd refer to an object's variable and replace it wth the new keyword,
- a call to a constructor and the class definition inside { and } characters.
- 454 The purpose will make more sense when you see how it replaces code that doesn't use one of these classes.
- 454 The following code creates a thread and starts it without using anonymous inner classes:
ThreadClass task = new ThreadClass();
Thread runner = new Thread(task);
runner.start();
- Top
- 454 For this example, assume the task object implements the Runnable interface to be run as a thread.
- Assume as well that the code in ThreadClass is simple and the class needs to be used only once.
- 454 In this situation, it's efficient to get rid of ThreadClass and put its code inside an anonymous inner class.
- This code rewite does exactly that:
Thread runner = new Thread(new Runnable() {
public void = run() {
// thread does its work here
}
});
runner.start();
- 454 The anonymous inner class has replaced the reference to task with the following code:
new Runnable() {
public void = run() {
// thread does its work here
}
}
- Top
- 454 In Java, calling the new operator is an expression that returns an object.
- So putting this code inside the Thread() constructor
- returns an unnamed object that implements the Runnable interface and overrides the run() method.
- The statements inside that method do the work that has been put in its own thread.
- 455 For a deeper look at this concept,
- the next project will be a full demonstration of how anonymous inner classes are created and why they're so useful.
- 455 On Day 12, "Responding to User Input," you learned about how to monitor user input in a Swing application by using interfaces called event listeners.
- When an application must monitor a particular type of input,
- such as a user clicking a button, moving a mouse, or typing keys on the keyboard, it must have a class that implements the listener interface for that input.
- These classes are in the package java.awt.event.
- Top
- 455 User clicks are monitored by KeyListener, for instance.
- 455 One event listener that was not covered is WindowListener, which tracks the different ways a user can interact with a window.
- 455 There are methods in the WindowListener interface for when a window has been opened and closed,
- as well as when it has because the focus or lost the focus.
- 455 A class that implements the interface must implement 10 methods:
- windowActivated()
- windowClosed()
- windowClosing()
- windowDeactivated()
- windowDeiconified()
- windowGainedFocus()
- windowIconified()
- windowLostFocus()
- windowOpened()
- windowStateChanged()
- Top
- 455 That's a lot of methods to implement, especially if you have only one or two possible window interactions that your class is interested in.
- A frame that only monitors when a window opened would have code that looked something like this:
public void windowOpened(WindowEvent event) {
Window pane = event.getWindow();
pane.setBackground(Color.CYAN);
}
public void windowClosed(WindowEvent event) {
// do nothing
}
public void windowActivated(WindowEvent event) {
// do nothing
}
public void windowDeactivated(WindowEvent event) {
// do nothing
}
- Top
- 455 That's just the part of the window event code required.
- There are another six do-nothing methods that must be present in a class that implements the WindowListener interface.
- 456 After all 10 methods are implemented in a frame, the frame can add a listener to monitor window events:
- Top
- 456 There's a better way to create the listener and add it to the frame: Use a subclass of the WindowAdapter class.
- 456 The WindowAdapter class implements the WindowListener interface as 10 methods that each do nothing.
- There are several adapter classes in the java.awt.event that simplify the proccess of listening to a particular event.
- You can create a subclass of the adapter class that overrides the method (or methods) only where something needs to happen.
- Top
- 456 Here's the code for a window listener that uses WindowAdapter and monitors the WindowClosing() event:
public class WindowCloseListener extends WindowAdapter {
JFrame frame;
boolean done;
public WindowCloseListener(JFrame inFrame) {
this.frame = inFrame;
}
public void WindowClosing(WindowEvent event) {
// user has tried to close window
if (frame.done) (
// allow it
frame.dispose();
System.exit(0);
}
}
}
- Top
- 456 Calling a window's dispose() method closes it.
- This code waits for a user to close a frame and does it only when the Boolean variable done equals true.
- That variable is an instance variable of a frame in another class (the one that created the listener).
- 456 In that frame, the frame's default behavior must be set to ignore attempts to close the window:
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
- 456 Also, the frame creates the listener object and makes a listener:
WindowCloseListener closer = new WindowCloseListener();
addWindowListener(closer);
- 457 An object of the helper class WindowCloseListener is assigned to a variable and set to monitor window events.
- Top
- 457 This approach to monitoring one window event requires four steps:
- Create a subclass of WindowAdapter.
- Implement the window closing method in that classd.
- Create a constructor in that class with the frame that needs the class as an argument.
- Store that frame in an instance variable.
- 457 The constructor and instance variable are needed to link the two classes.
- The adapter must be able to access the frame's done variable.
- Top
- 457 A simpler approach can be accomplished in the frame's class through the use of an anonymous inner class:
-
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
// user has tried to close window
if (frame.done) {
frame.dispose();
System.exit(0);
}
});
- 457 The listener is created anonymously by calling new WindowAdapter() with a definition of the class.
- The class overrides the WindowClosing() method so that when a user closes a window, an action can be taken.
- 457 This anonymous inner class can do something that a separate helper class could not do --- access the frame instance variable.
- Inner classes are able to access the methods and variables of their enclosing class, just like instance variables and methods.
- Top
- 457 NOTE: There are other adapter classes in the java.awt.event packages that make it convenient to implement other listeners.
- The KeyAdapter class has empty methods for keyboard events, MouseAdapter for mouse events, and FocusAdapter for keyboard focus events.
Second Program
- Top
- 458 During Day 10, "Building a Swing Interface," you created a ProgressMonitor application that used a slider as a progress bar.
- The next project today will enhance that code to prevent the program's main window from being closed if the progress bar has not reached 100 percent.
- 458 In NetBeans, create a new empty Java file named ProgressMonitor2 in the class (should be package) com.java21days,
- then enter the text of Listing 16.2 into that file.
- Save your work when you're done.
LISTING 16.2 The Full Text of ProgressMonitor2.java
- Top
- page 458-459
package com.java21days;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ProgressMonitor2 extends JFrame {
JProgressBar current;
int num = 0;
boolean done = false;
public ProgressMonitor2() {
super("Progress Monitor 2");
setLookAndFeel();
setDefaultCloseOperation(JFRame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent event) {
// user has tried to close window
if (done) {
// allow it
dispose();
System.exit(0);
}
}
});
setSize(400, 100);
setLayout(new FlowLayout());
current = new JProgressBar(0, 2000);
current.setValue(0);
current.setStringPainted(true);
current.setPreferredSize(new Dimension(360, 48));
add(current);
setVisible(true);
iterate();
}
public final void iterate() {
while (num < 2000) {
current.setValue(num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) { }
num += 95;
}
done = true;
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
);
SwingUtilities.updateComponentTreeUI(this);
} catch(Exception e) {
System.err.println("Couldn't use the system "
+ "look and feel: " + e);
}
}
public static void main(String[] arguments) {
new ProgressMonitor2();
}
}
The Explanation
- Top
- 459 The anonymous inner class is created and used in Lines 16 - 26.
- It monitors window input using WindowClosing(),
- the only method in the WindowListener interface the application needs to check,
- and makes sure the done instance variable equals true before closing the window.
- 459 See Figure 16.2 for the program's output.
Figure 16.2 - Stopping a program from closing until its work is done. - goes here
- 459 Anonymous inner classes cannot have a constructor, making them more limited than other inner classes and helper classes.
- Top
- 459 Anonymous inner classes are a bit more complex than other aspects of the Java language.
- They look odd in the source code of a program, and getting the punctuation right is tricky as you begin working with them.
- When you've added them to your skill set, you will find that they are a powerful, flexible, and concise way to get things done.
Closures
- Top
- 460 Java 8 adds the most highly requested language feature in years: closures.
- Programmers of other languages that offer them, such as Scala and Smalltalk,
- have clamored for them during the development of the past several releases.
- 460 Closures, also called lambda expressions, enable an object from a class with only a single method to be created with an -> operator,
- provided that other conditions are met.
- 460 This statement is an example:
Runnable runner = () -> { System.out.println("Eureka!");};
- 460 This code creates an object that implements the Runnable interface with a run() method equivalent to the following code:
public void run() {
System.out.println("Eureka!");
};
- Top
- 460 In a closure, the statement to the right of the -> arrow operator defines the method that implements the interface.
- 460 This is possible only when the interface has a single method to implement, as Runnable does with only the run() method.
- When an interface in Java has one method, it's now called a functional interface.
- 460 As you might have spotted, a closure also has something unusual to the left of the arrow operator.
- In the Runnable example, it's an empty set of parentheses.
- 460 This part of the expression holds the argument to send the method of the functional interface.
- The run() takes no arguments in the Runnable interface, so no arguments are required in that expression.
- 460 Take a look at another example of a closure that does have something inside the parentheses on the left side of the expression:
ActionListener listen = (ActionEvent act) -> {
System.out.println(act.getSource());
};
- 460 The closure provides an implementation of the only method in the ActionListener interface, actionPerformed().
- That method takes one argument, an ActionEvent object.
- ActionListener is in the java.awt.event package.
- Top
- 461 Here's the nonclosure way to implement the same functionality:
public void actionPerformed(ActionEvent act) {
System.out.println(act.getSource());
}
- 461 The ActionListener interface handles action events such as a user's button click or menu item selection.
- The only method in the functional interface is actionPerformed(ActionEvent).
- The argument contains the user action that triggered the event.
- 461 The right half of the closure defines the actionPerformed() method
- as a statement that displays information about the interface component where the event happened.
- The left half makes an ActionEvent object the argument to the method.
- 461 This object, act, is used inside the body of the method.
- In the closure, the left-half reference to act appears to be outside the scope of the right-half method implementation.
- Closures allow code to refer to variables of another method outside the scope of those variables.
- Top
- 461 Like anonymous inner classes, closures have the effect of making code shorter.
- A single expression creates an object and implements an interface.
- 461 Closures can make code even shorter through Java's support for target typing.
- 461 In a closure, it's possible to infer the class of the argument (or arguments) sent to the method.
- In the ActionListener example, the functional interface has a method with an ActionEvent object as its only argument.
- For this reason, the name of the class can be ommitted.
- 461 Here's a simplified version of the closure taking this into account:
ActionListener listen = (act) -> {
System.out.println(act.getSource());
}
- Top
- 461 Today's final two programs illustrate the difference that closures bring to Java.
- Top
- 461 The CursorMayhem application in Listing 16.3 is a Swing program that displays three buttons in a panel that change the program's cursor.
Cursors
- Top
- 461 Cursors have not been covered up to this point, but they're simple to use.
- They're represented by the Cursor class in the java.awt package and can be changed by calling a container's setCursor(Cursor) method.
- 462 The type of cursor is determined by class variables of the class.
- The following statements create a panel and set its current cursor to the one used in text boxes:
JPanel panel = new JPanel();
panel.setCursor(new Cursor(Cursor.TEXT_CURSOR));
- 462 This statement sets the cursor back to the default:
- panel.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
Third Program - Listing 16.3
- Top
- 462 This application will be implemented two different ways.
- The first version uses an anonymous inner class, not a closure, to monitor user clicks on the three buttons.
- Create a new program in NetBeans with the name CursorMeyhem and the package com.java21days, then type in the text in Listing 16.3.
LISTING 16.3 The Full Text of CursorMayhem.java
- Top
- page 462-463
package com.java21days;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CursorMayhem extends JFrame {
JButton harry, wade, hansel;
public CursorMayhem() {
super("Choose a Cursor");
setLookAndFeel();
setSize(400, 80);
setDefaultCloseOperation(JFRame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
harry = new JButton("Crosshair");
add(harry);
wade = new JButton("Wait");
add(wade);
hansel = new JButton("Hand");
add(hansel);
// begin anonymous inner class
ActionListener act = new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == harry) {
setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
}
if (event.getSource() == wade) {
setCursor(new Cursor(Cursor.WAIT_CURSOR));
}
if (event.getSource() == hansel) {
setCursor(new Cursor(Cursor.HAND_CURSOR));
}
}
};
// end anonymous inner class
harry.addActionListener(act);
wade.addActionListener(act);
hansel.addActionListener(act);
setVisible(true);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
);
} catch(Exception exc) {
System.err.println("Look and feel error: " + exc);
}
}
public static void main(String[] arguments) {
new CursorMayhem();
}
}
- Top
- 463 This program is shown running in Figure 16.3
Figure 16.3 - Monitoring action events with an anonymous inner class. - goes here
The Explanation
- Top
- 463 Lines 23 - 35 of the application define an event listener for the CursorMayhem class using an anonymous inner class.
- This nameless object contains an implementation of the only method in the ActionListener interface: actionPerformed(ActionEvent).
- 463 In the method, the frame's cursor is changed by calling its setCursor() method.
- Anonymous inner classes have access to the methods and instance variables of their enclosing class.
- A separate helper class would lack that access.
- 463 As you are running the app, move your cursor over the title bar that reads "Choose a Cursor."
- It changes from the current cursor to the default.
- Move it back over the pane and it becomes the cursor that you selected again.
Fourth Program - Listing 16.4
- Top
- 464 Now take a look at the ClosureMayhem application in Listing 16.4
LISTING 16.4 The Full Text of ClosureMayhem.java
- Top
- page 464-465
package com.java21days;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ClosureMayhem extends JFrame {
JButton harry, wade, hansel;
public ClosureMayhem() {
super("Choose a Cursor");
setLookAndFeel();
setSize(400, 80);
setDefaultCloseOperation(JFRame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
harry = new JButton("Crosshair");
add(harry);
wade = new JButton("Wait");
add(wade);
hansel = new JButton("Hand");
add(hansel);
// begin closure
ActionListener act = (event) -> {
if (event.getSource() == harry) {
setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
}
if (event.getSource() == wade) {
setCursor(new Cursor(Cursor.WAIT_CURSOR));
}
if (event.getSource() == hansel) {
setCursor(new Cursor(Cursor.HAND_CURSOR));
}
};
// end anonymous inner class
harry.addActionListener(act);
wade.addActionListener(act);
hansel.addActionListener(act);
setVisible(true);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
);
} catch(Exception exc) {
System.err.println("Look and feel error: " + exc);
}
}
public static void main(String[] arguments) {
new ClosureMayhem();
}
}
The Explanation
- Top
- 465 The ClosureMayhem application implements the action listener in lines 23 - 33
- Everything else is the same as in CursorMayhem, except for the lines that refer to the class name.
- 465 In ClosureMayhem, you don't need to know the name of the method in the ActionListener interface to use it in the program.
- You also don't need to specify the class of the ActionEvent that is the method's only argument.
- 465 Closures support functional programming, a methodology for software design that has before Java 8 been unavailable in the language.
- 465 With the basic syntax of closures and two common ways they can be employed in programs,
- you can begin to exploit this feature.
- At this point you should be able to recognize closures, write statements involving the arrow operator ->,
- and use it to create an object for any single-method interface.
- Top
- 465 These single-method interfaces also are called functional interfaces.
Summary
- Top
- 465 Like generics, inner classes, anonymous inner classes, and closures are among the most sophisticated aspects of Java.
- These advanced features are most important to programmers who have been working in the language long enough
- to develop a high level of experience in its use.
- An expert coder knows how to employ these features to do more in less code.
- 465 Before you reach a point where you are comfortable writing closures, you ought to be able to benefit from inner classes and anonymous inner classes.
- 465 A non-anonymous inner class takes the form of a helper class, situated inside a class instead of on its own.
- The class is defined with the instance variables, class variables, instance methods,
- and class methods that make up the behavior and attributes of the enclosing class.
- Because it's defined inside that class, the inner class can read and write its private variables and methods of the class.
- 466 An anonymous inner class is created without needing a variable, which makes sense for an object that will be used only once in a program.
- These classes often are used when a Swing user interface component needs an event listener to monitor user input.
- 466 Closures are deceptively similar in appearance, requiring only the new -> arrow operator to create,
- but offer an enormous enhancement to a Java programmer's capabilities.
Q & A
- Top
- Q Is it necessary to use anonymous inner classes ?
- A Whenever you can get something done without a feature of the Java language, you don't have to use that feature.
- Programmers generally can accomplish a task in a program in a buch of different ways.
- Though any sophisticated new technique is likely to work in fewer lines of code or offer other advantages,
- there's no penalty in Java for doing something in more statements.
- Generally, what matters is that your program works, not how many lines it took to make that happen.
- With that disclaimer, you should become conversant in features such as anonymous inner classes anyway.
- They are something you are going to find in Java code.
- Experienced programmers use inner classes, anonymous inner classes, and closures.
- Knowing what they are will help you understand what someone else's code is doing.
- Q Why are closures also called lambda expressions ?
- A The term "lambda" comes from the system of math logic called lambda calculus, where the Greek letter lambda represents an anonymous function.
- The choice of this letter was arbitrary.
- Lambda calculus has proven to be extremely useful in math, computation theory, and computer programming.
- Closures are available in many programming languages today in addition to Java.
- They include JavaScript, Python, C#, Scala, Smalltalk, and Haskell.
Quiz - Questions
- Top | Review today's material by taking this three-question quiz.
- Whatcan an inner class access that a separate helper class could not ?
- Anonymous inner classes
- private variables of another class
- Threads
- What makes a Java interface qualified to be called a functional interface ?
- The number of methods in that interface
- The arrow operator
- Any interface can be functional.
- What does an adapter class make easier ?
- The use of closures
- Arranging Swing user interface components
- Implementing an event listener
Answers
- Top | Note A is 1, B is 2, and C is 3
- B. An inner class can access the private variables and methods of its enclosing class.
- A. An interface that defines only one method is a functional interface.
- C. An adapter implements all the methods in an event listener interface so you can subclass the adapter and override only the method or methods that are useful.
Certification Practice
- Top
- 467 The following question is the kind of thing you could expect to be asked on a Java programming certification test. Answer it without looking at today's material or using the Java compiler to test the code.
- The answer is available on the book's website at www.java21days.com
- Given:
public class ClassType {
public static void main(String[] arguments) {
Class c = String.class;
try {
Object o = c.newInstance();
if (o instanceof String) {
System.out.println("True");
} else {
System.out.println("False");
}
} catch (Exception e) {
System.out.println("Error");
}
}
}
- What will be the output of this application ?
- true
- false
- Error
- The program will not compile.
Exercise
- Top
- To extend your knowledge of the subjects covered today, try the following exercises:
- Create a new version of the DiceRoller program from Day 14, "Developing Swing Applications," that makes DiceWorker an inner class.
- Extend your new DiceRoller program to monitor action events with a closure.