java handler null_避免!= null语句

Null不是'problem' . 它是complete建模工具集的组成部分 . 软件旨在模拟世界的复杂性,而null则承担其负担 . 在Java等中 Null indicates 'No data' or 'Unknown' . 因此,为这些目的使用null是合适的 . 我没有't prefer the ' Null对象' pattern; I think it rise the ' who will guard the guardians'问题 .

如果你问我女朋友的名字是什么我'll tell you that I have no girlfriend. In the Java language I'将返回null . 另一种方法是抛出有意义的异常,以指示可以在那里解决的一些问题,并将其委托给堆栈中较高的位置,以重试或向用户报告数据访问错误 .

For an 'unknown question' give 'unknown answer'. (从业务角度来看,这是正确的 . )在使用之前在方法内部检查一次null参数可以减少多个调用者在调用之前检查它们 .

public Photo getPhotoOfThePerson(Person person) {

if (person == null)

return null;

// Grabbing some resources or intensive calculation

// using person object anyhow.

}

上一步导致正常的逻辑流程,从我的照片库中没有任何不存在的女朋友的照片 .

getPhotoOfThePerson(me.getGirlfriend())

它适合新的Java API(期待)

getPhotoByName(me.getGirlfriend()?.getName())

虽然对于某些人来说,不是为了找到存储在数据库中的照片而是“正常的业务流程”,但我过去常常使用如下所示的对来用于其他一些情况

public static MyEnum parseMyEnum(String value); // throws IllegalArgumentException

public static MyEnum parseMyEnumOrNull(String value);

并且不要厌恶键入 + + (在Eclipse中生成javadoc)并为您的公共API写下三个额外的单词 . 对于那些没有阅读文档的人来说,这将是绰绰有余的 .

/**

* @return photo or null

*/

要么

/**

* @return photo, never null

*/

This is rather theoretical case and in most cases you should prefer java null safe API (in case it will be released in another 10 years), but NullPointerException is subclass of an Exception. 因此它是 Throwable 的一种形式,表示合理的应用程序可能想要捕获的条件(javadoc)!为了使用'regular'代码(according to creators of Java)中的第一个最有利的异常和单独的错误处理代码,对我来说, grab NullPointerException 是合适的 .

public Photo getGirlfriendPhoto() {

try {

return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().getName());

} catch (NullPointerException e) {

return null;

}

}

可能会出现问题:

问:如果 getPhotoDataSource() 返回null,该怎么办?

答:这取决于业务逻辑 . 如果我找不到相册,那么'll show you no photos. What if appContext is not initialized? This method'的商业逻辑就会出现这种情况 . 如果相同的逻辑应该更严格,那么抛出异常它就是业务逻辑的一部分,应该使用null的显式检查(情况3) . new Java Null-safe API fits better here to specify selectively what implies and what does not imply to be initialized 在程序员错误的情况下是快速失败的 .

问:可以执行冗余代码并且可以获取不必要的资源 .

答:如果 getPhotoByName() 尝试打开数据库连接,创建 PreparedStatement 并最后使用人名作为SQL参数,则可能会发生这种情况 . 针对未知问题的方法给出了未知答案(案例1) . 在获取资源之前,该方法应检查参数并在需要时返回'unknown'结果 .

问:由于尝试关闭开放,这种方法会带来性能损失 .

答:首先应该易于理解和修改软件 . 只有在此之后,才能考虑性能,只有在需要时!并在需要的地方! (source),以及许多其他人) .

PS . 这种方法可以合理使用,因为"regular"代码原则的单独错误处理代码在某些地方使用是合理的 . 考虑下一个例子:

public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {

try {

Result1 result1 = performSomeCalculation(predicate);

Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());

Result3 result3 = performThirdCalculation(result2.getSomeProperty());

Result4 result4 = performLastCalculation(result3.getSomeProperty());

return result4.getSomeProperty();

} catch (NullPointerException e) {

return null;

}

}

public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {

SomeValue result = null;

if (predicate != null) {

Result1 result1 = performSomeCalculation(predicate);

if (result1 != null && result1.getSomeProperty() != null) {

Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());

if (result2 != null && result2.getSomeProperty() != null) {

Result3 result3 = performThirdCalculation(result2.getSomeProperty());

if (result3 != null && result3.getSomeProperty() != null) {

Result4 result4 = performLastCalculation(result3.getSomeProperty());

if (result4 != null) {

result = result4.getSomeProperty();

}

}

}

}

}

return result;

}

PPS . 对于那些快速下载(并且读取文档的速度不够快)的人,我想说我的生活中从未遇到过空指针异常(NPE) . 但这种可能性是Java创建者的 intentionally designed 因为NPE是 Exception 的子类 . 我们在Java历史上有一个先例,当 ThreadDeath 是 Error 时,并不是因为它实际上是一个应用程序错误,而仅仅是因为它不打算被捕获! NPE比 ThreadDeath 多少适合 Error !但事实并非如此 .

Check for 'No data' only if business logic implies it.

public void updatePersonPhoneNumber(Long personId, String phoneNumber) {

if (personId == null)

return;

DataSource dataSource = appContext.getStuffDataSource();

Person person = dataSource.getPersonById(personId);

if (person != null) {

person.setPhoneNumber(phoneNumber);

dataSource.updatePerson(person);

} else {

Person = new Person(personId);

person.setPhoneNumber(phoneNumber);

dataSource.insertPerson(person);

}

}

public void updatePersonPhoneNumber(Long personId, String phoneNumber) {

if (personId == null)

return;

DataSource dataSource = appContext.getStuffDataSource();

Person person = dataSource.getPersonById(personId);

if (person == null)

throw new SomeReasonableUserException("What are you thinking about ???");

person.setPhoneNumber(phoneNumber);

dataSource.updatePerson(person);

}

如果未初始化appContext或dataSource,则未处理的运行时NullPointerException将终止当前线程并将由Thread.defaultUncaughtExceptionHandler处理(您可以定义和使用您喜欢的 Logger 或其他通知机制) . 如果未设置,ThreadGroup#uncaughtException将打印堆栈跟踪到系统错误 . 应该监视应用程序错误日志并为每个未处理的异常打开Jira问题,这实际上是应用程序错误 . 程序员应该在初始化的东西中修复bug .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值