How are Anonymous inner classes used in Java?

后端 未结 18 1394
孤独总比滥情好
孤独总比滥情好 2020-11-21 05:19

What is the use of anonymous classes in Java? Can we say that usage of anonymous class is one of the advantages of Java?

18条回答
  •  一个人的身影
    2020-11-21 06:06

    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 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.

提交回复
热议问题