An inner class is associated with an instance of the outer class and there are two special kinds: Local class and Anonymous class. An anonymous class enables us to declare and instantiate a class at same time, hence makes the code concise. We use them when we need a local class only once as they don't have a name.
Consider the example from doc where we have a Person
class:
public class Person {
public enum Sex {
MALE, FEMALE
}
String name;
LocalDate birthday;
Sex gender;
String emailAddress;
public int getAge() {
// ...
}
public void printPerson() {
// ...
}
}
and we have a method to print members that match search criteria as:
public static void printPersons(
List<Person> roster, CheckPerson tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
where CheckPerson
is an interface like:
interface CheckPerson {
boolean test(Person p);
}
Now we can make use of anonymous class which implements this interface to specify search criteria as:
printPersons(
roster,
new CheckPerson() {
public boolean test(Person p) {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
}
);
Here the interface is very simple and the syntax of anonymous class seems unwieldy and unclear.
Java 8 has introduced a term Functional Interface which is an interface with only one abstract method, hence we can say CheckPerson
is a functional interface. We can make use of Lambda Expression which allows us to pass the function as method argument as:
printPersons(
roster,
(Person p) -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
We can use a standard functional interface Predicate
in place of the interface CheckPerson
, which will further reduce the amount of code required.