The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.
SeeDev.java for updated tutorials taking advantage of the latest releases.
SeeJava Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.
SeeJDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.
Anonymous classes enable you to make your code more concise.They enable you to declare and instantiate a class at the sametime. They are like local classes except that they do not have aname. Use them if you need to use a local class only once.
This section covers the following topics:
While local classes are class declarations, anonymous classesare expressions, which means that you define the class in anotherexpression. The following example,HelloWorldAnonymousClasses
, uses anonymous classes in the initialization statements of thelocal variablesfrenchGreeting
andspanishGreeting
, but uses a local class for theinitialization of the variableenglishGreeting
:
public class HelloWorldAnonymousClasses { interface HelloWorld { public void greet(); public void greetSomeone(String someone); } public void sayHello() { class EnglishGreeting implements HelloWorld { String name = "world"; public void greet() { greetSomeone("world"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hello " + name); } } HelloWorld englishGreeting = new EnglishGreeting(); HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde"; public void greet() { greetSomeone("tout le monde"); } public void greetSomeone(String someone) { name = someone; System.out.println("Salut " + name); } }; HelloWorld spanishGreeting = new HelloWorld() { String name = "mundo"; public void greet() { greetSomeone("mundo"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hola, " + name); } }; englishGreeting.greet(); frenchGreeting.greetSomeone("Fred"); spanishGreeting.greet(); } public static void main(String... args) { HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses(); myApp.sayHello(); } }
As mentioned previously, an anonymous class is an expression.The syntax of an anonymous class expression is like theinvocation of a constructor, except that there is a class definitioncontained in a block of code.
Consider the instantiation of thefrenchGreeting
object:
HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde"; public void greet() { greetSomeone("tout le monde"); } public void greetSomeone(String someone) { name = someone; System.out.println("Salut " + name); } };
The anonymous class expression consists of the following:
Thenew
operator
The name of an interface toimplement or a class to extend. In this example, the anonymousclass is implementing the interfaceHelloWorld
.
Parentheses that contain thearguments to a constructor, just like a normal class instancecreation expression.Note: When you implement aninterface, there is no constructor, so you use an empty pair ofparentheses, as in this example.
A body, which is a classdeclaration body. More specifically, in the body, methoddeclarations are allowed but statements are not.
Because an anonymous classdefinition is an expression, it must be part of a statement. Inthis example, the anonymous class expression is part of thestatement that instantiates thefrenchGreeting
object. (Thisexplains why there is a semicolon after the closing brace.)
Like local classes, anonymous classes cancapture variables; they have the same access to local variables ofthe enclosing scope:
An anonymous class has access to the members of its enclosingclass.
An anonymous class cannot access local variables in itsenclosing scope that are not declared asfinal
or effectively final.
Like a nested class, a declaration of a type (such as a variable) in an anonymous class shadows any other declarations in the enclosing scope that have the same name. SeeShadowing for more information.
Anonymous classes also have the same restrictions as localclasses with respect to their members:
You cannot declare staticinitializers or member interfaces in an anonymousclass.
An anonymous class canhave static members provided that they are constantvariables.
Note that you can declare the following in anonymous classes:
Fields
Extra methods (even if they do not implement any methods of the supertype)
Instance initializers
Local classes
However, you cannot declare constructors in an anonymous class.
Anonymous classes are often used in graphical userinterface (GUI) applications.
Consider the JavaFX exampleHelloWorld.java
(from the sectionHello World, JavaFX Style fromGetting Started with JavaFX). Thissample creates a frame that contains aSay 'Hello World'button. The anonymous classexpression is highlighted:
import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.layout.StackPane;import javafx.stage.Stage; public class HelloWorld extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Hello World!"); Button btn = new Button(); btn.setText("Say 'Hello World'"); btn.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {System.out.println("Hello World!");}}); StackPane root = new StackPane(); root.getChildren().add(btn); primaryStage.setScene(new Scene(root, 300, 250)); primaryStage.show(); }}
In this example, the method invocationbtn.setOnAction
specifies what happens when you select theSay 'Hello World' button. This method requires an object of typeEventHandler<ActionEvent>
. TheEventHandler<ActionEvent>
interface contains only one method, handle. Instead of implementing this method with a new class, the example uses an anonymous class expression. Notice that this expression is the argument passed to thebtn.setOnAction
method.
Because theEventHandler<ActionEvent>
interface contains only one method, you can use a lambdaexpression instead of an anonymous class expression. See thesectionLambda Expressions for moreinformation.
Anonymous classes are ideal for implementing an interface that contains two or more methods. The following JavaFX example is from the section Customization of UI Controls. The highlighted code creates a text field that only accepts numeric values. It redefines the default implementation of theTextField
class with an anonymous class by overriding thereplaceText
andreplaceSelection
methods inherited from theTextInputControl
class.
import javafx.application.Application;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.geometry.Insets;import javafx.scene.Group;import javafx.scene.Scene;import javafx.scene.control.*;import javafx.scene.layout.GridPane;import javafx.scene.layout.HBox;import javafx.stage.Stage;public class CustomTextFieldSample extends Application { final static Label label = new Label(); @Override public void start(Stage stage) { Group root = new Group(); Scene scene = new Scene(root, 300, 150); stage.setScene(scene); stage.setTitle("Text Field Sample"); GridPane grid = new GridPane(); grid.setPadding(new Insets(10, 10, 10, 10)); grid.setVgap(5); grid.setHgap(5); scene.setRoot(grid); final Label dollar = new Label("$"); GridPane.setConstraints(dollar, 0, 0); grid.getChildren().add(dollar); final TextField sum =new TextField() {@Overridepublic void replaceText(int start, int end, String text) {if (!text.matches("[a-z, A-Z]")) {super.replaceText(start, end, text);}label.setText("Enter a numeric value");}@Overridepublic void replaceSelection(String text) {if (!text.matches("[a-z, A-Z]")) {super.replaceSelection(text);}}}; sum.setPromptText("Enter the total"); sum.setPrefColumnCount(10); GridPane.setConstraints(sum, 1, 0); grid.getChildren().add(sum); Button submit = new Button("Submit"); GridPane.setConstraints(submit, 2, 0); grid.getChildren().add(submit); submit.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { label.setText(null); } }); GridPane.setConstraints(label, 0, 1); GridPane.setColumnSpan(label, 3); grid.getChildren().add(label); scene.setRoot(grid); stage.show(); } public static void main(String[] args) { launch(args); }}
About Oracle |Contact Us |Legal Notices |Terms of Use |Your Privacy Rights
Copyright © 1995, 2024 Oracle and/or its affiliates. All rights reserved.