Java: avoid checking for null in nested classes (Deep Null checking)

前端 未结 11 491
失恋的感觉
失恋的感觉 2020-12-05 09:12

Imagine I have a class Family. It contains a List of Person. Each (class) Person contains a (class) Address. Each (class) Address contains a (class) PostalCode. Any "i

11条回答
  •  佛祖请我去吃肉
    2020-12-05 09:55

    Instead of using null, you could use some version of the "null object" design pattern. For example:

    public class Family {
        private final PersonList people;
        public Family(PersonList people) {
            this.people = people;
        }
    
        public PersonList getPeople() {
            if (people == null) {
                return PersonList.NULL;
            }
            return people;
        }
    
        public boolean isNull() {
            return false;
        }
    
        public static Family NULL = new Family(PersonList.NULL) {
            @Override
            public boolean isNull() {
                return true;
            }
        };
    }
    
    
    import java.util.ArrayList;
    
    public class PersonList extends ArrayList {
        @Override
        public Person get(int index) {
            Person person = null;
            try {
                person = super.get(index);
            } catch (ArrayIndexOutOfBoundsException e) {
                return Person.NULL;
            }
            if (person == null) {
                return Person.NULL;
            } else {
                return person;
            }
        }
        //... more List methods go here ...
    
        public boolean isNull() {
            return false;
        }
    
        public static PersonList NULL = new PersonList() {
            @Override
            public boolean isNull() {
                return true;
            }
        };
    }
    
    public class Person {
        private Address address;
    
        public Person(Address address) {
            this.address = address;
        }
    
        public Address getAddress() {
            if (address == null) {
                return Address.NULL;
            }
            return address;
        }
        public boolean isNull() {
            return false;
        }
    
        public static Person NULL = new Person(Address.NULL) {
            @Override
            public boolean isNull() {
                return true;
            }
        };
    }
    
    etc etc etc
    

    Then your if statement can become:

    if (!family.getPeople().get(0).getAddress().getPostalCode.isNull()) {...}
    

    It's suboptimal since:

    • You're stuck making NULL objects for every class,
    • It's hard to make these objects generic, so you're stuck making a null-object version of each List, Map, etc that you want to use, and
    • There are potentially some funny issues with subclassing and which NULL to use.

    But if you really hate your == nulls, this is a way out.

提交回复
热议问题