Local classes

Unlike inner classes, a local class is declared in a block of Java code. Usually, a local class is defined in a method, but it can also be defined in a static or instance initializer, and in general in any block of code. Since all blocks of Java code are inside the class definition, all local classes are nested within the surrounding classes. For this reason, local classes have a lot in common with inner classes. But more often they are considered as a separate kind of inner classes.

The visibility of a local class is governed by the scope of the block in which it is declared. But at the same time, the local class retains access to all fields and methods of the outer class, as well as to all constants declared in the current block of code, that is, the fields and method arguments declared as final. But starting with JDK 8, a local class can access any fields and method arguments declared in the current block of code, even if they are not declared as final, but only if their value does not change after initialization, essentially the same eggs only look with side. Such variables or arguments, the value of which does not change after their initialization, are called (in JDK8 terminology) – effectively final.

Local classes are never declared with access modifiers (i.e. public, protected, etc.), because their scope is always limited to the block in which they are declared.

A local class is visible only within the block that defines it; it cannot be applied outside of this block.

Like inner classes, and for the same reasons, local classes cannot contain static fields, methods, or classes. The only exceptions are constants declared static and final.

Interfaces cannot be defined locally.

Like an inner class, a local class cannot be named the same as its surrounding class.

As noted earlier, a local class can use local variables, method parameters that are in its scope, and even exception parameters of the catch statement, but only those that are declared final. This is because the lifetime of a local class can significantly exceed the execution time of the method in which the class is defined. For this reason, a local class must have its own internal copies of all local variables that it uses (these copies are automatically generated by the compiler). The only way to ensure that the values ​​of a local variable and its copy are identical is to declare the local variable final. Again, let me remind you that this was all true up to and including JDK 7. In JDK 8, the situation has changed and you can do without declaring a variable as final, but not change its value in the code after initialization. Although by and large it is better, for self-control, to declare variables as final.

Instances of local classes, like instances of inner classes, have an enclosing instance, a reference to which is implicitly passed to all constructors of local classes. Local classes can use the same this syntax that inner classes use to explicitly refer to the enclosing class object or members. Since local classes are not visible outside the block in which they are defined, there is no need to use the new syntax applied to inner classes to explicitly specify the surrounding instance when instantiating the local class.

Local classes can inherit any other classes and naturally access the members of these classes if they are not declared as private, which, in principle, is natural and does not violate general rules, since inherited members become members of the inherited class, and private members cannot be inherited, for that they are private.

It is also natural that local classes cannot act as parent classes, since their scope is limited to any block of Java code. An exception is the case when the inheritance of a local class by another local class occurs in the same block of code, but this is generally a crazy situation, although it is quite possible

Now let’s practice a little …


And I will immediately give the output of this program, provided that it was compiled in JDK8:


Highlighted in red are two lines that will cause a compilation error if compiled in JDK7 or lower, since afStr and noFinal do not have the final modifier.