我使用x!=null以避免NullPointerException。还有其他选择吗?

if (x != null) {
    // ...
}

当前回答

在Java8中,如果局部变量/字段/方法参数/方法返回类型从未赋值为null(并且不检查null),则可以使用类型T;如果可以为null,则可以键入Optional<T>。然后使用方法map处理T->,使用方法flatMap处理T->可选<R>:

class SomeService {
    @Inject
    private CompanyDao companyDao;

    // return Optional<String>
    public Optional<String> selectCeoCityByCompanyId0(int companyId) {
        return companyDao.selectById(companyId)
                .map(Company::getCeo)
                .flatMap(Person::getHomeAddress)
                .flatMap(Address::getCity);
    }

    // return String + default value
    public String selectCeoCityByCompanyId1(int companyId) {
        return companyDao.selectById(companyId)
                .map(Company::getCeo)
                .flatMap(Person::getHomeAddress)
                .flatMap(Address::getCity)
                .orElse("UNKNOWN");
    }

    // return String + exception
    public String selectCeoCityByCompanyId2(int companyId) throws NoSuchElementException {
        return companyDao.selectById(companyId)
                .map(Company::getCeo)
                .flatMap(Person::getHomeAddress)
                .flatMap(Address::getCity)
                .orElseThrow(NoSuchElementException::new);
    }
}

interface CompanyDao {
    // real situation: no company for such id -> use Optional<Company> 
    Optional<Company> selectById(int id);
}

class Company {
    // company always has ceo -> use Person 
    Person ceo;
    public Person getCeo() {return ceo;}
}

class Person {
    // person always has name -> use String
    String firstName;
    // person can be without address -> use Optional<Address>
    Optional<Address> homeAddress = Optional.empty();

    public String getFirstName() {return firstName;}   
    public Optional<Address> getHomeAddress() {return homeAddress;}
}

class Address {
    //  address always contains country -> use String
    String country;
    //  city field is optional -> use Optional<String>
    Optional<String> city = Optional.empty();

    String getCountry() {return country;}    
    Optional<String> getCity() {return city;}
}

其他回答

切勿将变量初始化为空。如果(1)不可能,则将所有集合和数组初始化为空集合/数组。

在您自己的代码中执行此操作,您可以避免!=空检查。

大多数时候,空检查似乎保护了集合或数组上的循环,所以只要将它们初始化为空,就不需要任何空检查。

// Bad
ArrayList<String> lemmings;
String[] names;

void checkLemmings() {
    if (lemmings != null) for(lemming: lemmings) {
        // do something
    }
}



// Good
ArrayList<String> lemmings = new ArrayList<String>();
String[] names = {};

void checkLemmings() {
    for(lemming: lemmings) {
        // do something
    }
}

这是一个很小的开销,但它值得更干净的代码和更少的NullPointerExceptions。

您可以考虑空对象是bug的情况,而不是空对象模式(有其用途)。

当抛出异常时,检查堆栈跟踪并解决错误。

还有一种选择:

下面的简单函数有助于隐藏空检查(我不知道为什么,但我没有发现它是同一个公共库的一部分):

public static <T> boolean isNull(T argument) {
    return (argument == null);
}

你现在可以写了

if (!isNull(someobject)) {
    someobject.doCalc();
}

这是IMO更好的表达方式!=无效的

无论您在何处传递数组或向量,请将它们初始化为空值,而不是空值。-这样可以避免大量检查null,一切都很好:)

public class NonNullThing {

   Vector vectorField = new Vector();

   int[] arrayField = new int[0];

   public NonNullThing() {

      // etc

   }

}

我更喜欢这个

public void simpleFunc(SomeObject someObject){
    someObject = someObject != null ? someObject : new SomeObject(null);
    someObject.doSomething();
}

当然,在我的示例中,SomeObject优雅地处理空参数。例如,记录这样的事件,不做任何其他操作。