技术开发 频道

Java开发中10个最为微妙的非常好的编程实践

  4. 现在就开始编写SAM!

  Java8的脚步近了。伴随着Java8带来了lambda表达式,无论你是否喜欢。尽管你的API使用者可能会喜欢,但是你最好确保他们可以尽可能经常的使用。因此除非你的API接收简单的“标量”类型,比如int、long、String 、Date,否则让你的API尽可能经常的接收SAM。

  什么是SAM?SAM是单一抽象方法[类型]。也称为函数接口,很快被注释为@FunctionalInterface。这与规则2很配,EventListener实际上就是一个SAM。最好的SAM只有一个参数,因为这将会进一步简化lambda表达式的编写。设想编写:

listeners.add(c -> System.out.println(c.message()));

  替代:

listeners.add(new EventListener() {
  @Override
  
public void message(MessageContext c) {
    System.out.println(c.message()));
  }
});

  设想以SAM的方式用jOOX处理XML:

$(document)
  
// Find elements with an ID
  .find(c
-> $(c).id() != null)
  
// Find their child elements
  .children(c
-> $(c).tag().equals("order"))
  
// Print all matches
  .each(c
-> System.out.println($(c)))

  规则:对你的API使用者好一点儿,从现在开始编写SAM/函数接口。

  5.避免让方法返回null

  我曾写过1、2篇关于java NULLs的文章,也讲解过Java8中引入新的Optional类。从学术或实用的角度来看,这些话题还是比较有趣的。

  尽管现阶段Null和NullPointerException依然是Java的硬伤,但是你仍可以设计出不会出现任何问题的API。在设计API时,应当尽可能的避免让方法返回null,因为你的用户可能会链式调用方法:

initialise(someArgument).calculate(data).dispatch();

  从上面代码中可看出,任何一个方法都不应返回null。实际上,在通常情况下使用null会被认为相当的异类。像 jQuery 或 jOOX这样的库在可迭代的对象上已完全的摒弃了null。

  Null通常用在延迟初始化中。在许多情况下,在不严重影响性能的条件下,延迟初始化也应该被避免。实际上,如果涉及的数据结构过于庞大,那么就要慎用延迟初始化。

  规则:无论何时方法都应避免返回null。null仅用来表示“未初始化”或“不存在”的语义。

  6.设计API时永远不要返回空(null)数组或List

  尽管在一些情况下方法返回值为null是可以的,但是绝不要返回空数组或空集合!请看 java.io.File.list()方法,它是这样设计的:

  此方法会返回一个指定目录下所有文件或目录的字符串数组。如果目录为空(empty)那么返回的数组也为空(empty)。如果指定的路径不存在或发生I/O错误,则返回null。

  因此,这个方法通常要这样使用:

File directory = // ...

if (directory.isDirectory()) {
  
String[] list = directory.list();

  
if (list != null) {
    
for (String file : list) {
      
// ...
    }
  }
}

  大家觉得null检查有必要吗?大多数I/O操作会产生IOExceptions,但这个方法却只返回了null。Null是无法存放I/O错误信息的。因此这样的设计,有以下3方面的不足:

  • Null无助于发现错误;

  • Null无法表明I/O错误是由File实例所对应的路径不正确引起的;

  • 每个人都可能会忘记判断null情况。

  以集合的思维来看待问题的话,那么空的(empty)的数组或集合就是对“不存在”的非常好的实现。返回空(null)数组或集合几乎是无任何实际意义的,除非用于延迟初始化。

  规则:返回的数组或集合不应为null。

0
相关文章