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.
Local classes are classes that are defined in ablock, whichis a group of zero or more statements between balanced braces.You typically find local classes defined in the body of amethod.
This section covers the following topics:
You can define a local class inside any block (seeExpressions, Statements, and Blocks for more information).For example, you can define a local class in a method body, afor
loop, or anif
clause.
The following example,LocalClassExample
, validates two phone numbers. It definesthe local classPhoneNumber
in the methodvalidatePhoneNumber
:
public class LocalClassExample { static String regularExpression = "[^0-9]"; public static void validatePhoneNumber( String phoneNumber1, String phoneNumber2) { final int numberLength = 10; // Valid in JDK 8 and later: // int numberLength = 10; class PhoneNumber { String formattedPhoneNumber = null; PhoneNumber(String phoneNumber){ // numberLength = 7; String currentNumber = phoneNumber.replaceAll( regularExpression, ""); if (currentNumber.length() == numberLength) formattedPhoneNumber = currentNumber; else formattedPhoneNumber = null; } public String getNumber() { return formattedPhoneNumber; } // Valid in JDK 8 and later:// public void printOriginalNumbers() {// System.out.println("Original numbers are " + phoneNumber1 +// " and " + phoneNumber2);// } } PhoneNumber myNumber1 = new PhoneNumber(phoneNumber1); PhoneNumber myNumber2 = new PhoneNumber(phoneNumber2); // Valid in JDK 8 and later:// myNumber1.printOriginalNumbers(); if (myNumber1.getNumber() == null) System.out.println("First number is invalid"); else System.out.println("First number is " + myNumber1.getNumber()); if (myNumber2.getNumber() == null) System.out.println("Second number is invalid"); else System.out.println("Second number is " + myNumber2.getNumber()); } public static void main(String... args) { validatePhoneNumber("123-456-7890", "456-7890"); }}
The example validates a phone number byfirst removing all characters from the phone number except thedigits 0 through 9. After, it checks whether the phone numbercontains exactly ten digits (the length of a phone number inNorth America). This example prints the following:
First number is 1234567890Second number is invalid
A local class has access to the members of its enclosingclass. In the previous example, thePhoneNumber
constructor accesses the memberLocalClassExample.regularExpression
.
In addition, a local class has access to local variables. However, a local class can only access local variables that are declared final. When a local class accesses a local variable or parameter of the enclosing block, itcaptures that variable or parameter. For example, thePhoneNumber
constructor can access the local variablenumberLength
because it is declared final;numberLength
is acaptured variable.
However, starting in Java SE 8, a local class can access local variables andparameters of the enclosing block that are final oreffectively final. A variable or parameter whose value is never changed after it is initialized is effectively final. For example, suppose that the variablenumberLength
is not declared final, and you add the highlighted assignment statement in thePhoneNumber
constructor to change the length of a valid phone number to 7 digits:
PhoneNumber(String phoneNumber) {numberLength = 7; String currentNumber = phoneNumber.replaceAll( regularExpression, ""); if (currentNumber.length() == numberLength) formattedPhoneNumber = currentNumber; else formattedPhoneNumber = null;}
Because of this assignmentstatement, the variablenumberLength
is not effectively final anymore. As a result, the Java compiler generates an error message similar to"local variables referenced from an inner class must be final or effectively final" where the inner classPhoneNumber
tries to access thenumberLength
variable:
if (currentNumber.length() == numberLength)
Starting in Java SE 8, if you declare the local class in a method, it can access the method's parameters. For example, you can define the following method in thePhoneNumber
local class:
public void printOriginalNumbers() { System.out.println("Original numbers are " + phoneNumber1 + " and " + phoneNumber2);}
The methodprintOriginalNumbers
accesses the parametersphoneNumber1
andphoneNumber2
of the methodvalidatePhoneNumber
.
Declarations of a type (such as a variable) in a local class shadow declarations in the enclosing scope that have the same name. SeeShadowing for more information.
Local classes are similar to inner classes because they cannot define or declare any static members. Local classes in static methods, such as the classPhoneNumber
, which is defined in the static methodvalidatePhoneNumber
, can only refer to static members of the enclosing class. For example, if you do not define the member variableregularExpression
as static, then the Java compiler generates an error similar to "non-static variableregularExpression
cannot be referenced from a static context."
Local classes are non-static because they have access toinstance members of the enclosing block. Consequently, theycannot contain most kinds of static declarations.
You cannot declare an interface inside a block; interfaces areinherently static. For example, the following code excerpt doesnot compile because the interfaceHelloThere
is defined inside thebody of the methodgreetInEnglish
:
public void greetInEnglish() { interface HelloThere { public void greet(); } class EnglishHelloThere implements HelloThere { public void greet() { System.out.println("Hello " + name); } } HelloThere myGreeting = new EnglishHelloThere(); myGreeting.greet(); }
You cannot declare staticinitializers or member interfaces in a local class. The followingcode excerpt does not compile because the methodEnglishGoodbye.sayGoodbye
is declaredstatic
. The compiler generates an errorsimilar to "modifier 'static' is only allowed in constantvariable declaration" when it encounters this methoddefinition:
public void sayGoodbyeInEnglish() { class EnglishGoodbye { public static void sayGoodbye() { System.out.println("Bye bye"); } } EnglishGoodbye.sayGoodbye(); }
A local class can havestatic members provided that they are constant variables. (Aconstant variable is a variable of primitive type or typeString
that is declared final and initialized with a compile-time constant expression. A compile-time constant expression is typically a string or an arithmetic expression that can be evaluated at compile time. SeeUnderstanding Class Members for more information.) Thefollowing code excerpt compiles because the static memberEnglishGoodbye.farewell
is aconstant variable:
public void sayGoodbyeInEnglish() { class EnglishGoodbye { public static final String farewell = "Bye bye"; public void sayGoodbye() { System.out.println(farewell); } } EnglishGoodbye myEnglishGoodbye = new EnglishGoodbye(); myEnglishGoodbye.sayGoodbye(); }
About Oracle |Contact Us |Legal Notices |Terms of Use |Your Privacy Rights
Copyright © 1995, 2024 Oracle and/or its affiliates. All rights reserved.