如何写出更好的Java代码(2)

发表于:2014-05-27来源:不详作者:不详点击数: 标签:
还有一个不错的方式是使用Dagger库以及Google的Guice。它们并没有使用Spring的XML配置文件的格式,而是将注入的逻辑放到了注解和代码里。 避免null值 如果有

  还有一个不错的方式是使用Dagger库以及Google的Guice。它们并没有使用Spring的XML配置文件的格式,而是将注入的逻辑放到了注解和代码里。

  避免null值

  如果有可能的话尽量避免使用null值。你可以返回一个空的集合,但不要返回null集合。如果你准备使用null的话,考虑一下@Nullable注解。IntelliJ IDEA对于@Nullable注解有内建的支持。

  如果你使用的是Java 8的话,可以考虑下新的Optional类型。如果一个值可能存在也可能不存在,把它封装到Optional类里面,就像这样:

  public class FooWidget {

  private final String data;

  private final Optional bar;

  public FooWidget(String data) {

  this(data, Optional.empty());

  }

  public FooWidget(String data, Optional bar) {

  this.data = data;

  this.bar = bar;

  }

  public Optional getBar() {

  return bar;

  }

  }

  现在问题就清楚了,data是不会为null的,而bar可能为空。Optional类有一些像isPresent这样的方法,这让它感觉跟检查null没什么区别。不过有了它你可以写出这样的语句:

  final Optional fooWidget = maybeGetFooWidget();

  final Baz baz = fooWidget.flatMap(FooWidget::getBar)

  .flatMap(BarWidget::getBaz)

  .orElse(defaultBaz);

  这比使用if来检查null好多了。唯一的缺点就是标准类库中对Optional的支持并不是很好,因此你还是需要对null进行检查的。

  不可变

  变量,类,集合,这些都应该是不可变的,除非你有更好的理由它们的确需要进行修改。

  变量可以通过final来设置成不可变的:

  final FooWidget fooWidget;

  if (condition()) {

  fooWidget = getWidget();

  } else {

  try {

  fooWidget = cachedFooWidget.get();

  } catch (CachingException e) {

  log.error("Couldn't get cached value", e);

  throw e;

  }

  }

  // fooWidget is guaranteed to be set here

  现在你可以确认fooWidget不会不小心被重新赋值了。final关键字可以和if/else块以及try/catch块配合使用。当然了,如果fooWidget对象不是不可变的,你也可以很容易地对它进行修改。

  有可能的话,集合都应该尽量使用Guava的ImmutableMap, ImmutableList, or ImmutableSet类。这些类都有自己的构造器,你可以动态的创建它们,然后将它们设置成不可变的,。

  要使一个类不可变,你可以将它的字段声明成不可变的(设置成final)。你也可以把类自身也设置成final的这样它就不能被扩展并且修改了,当然这是可选的。

  避免大量的工具类

  如果你发现自己添加了许多方法到一个Util类里,你要注意了。

  public class MiscUtil {

  public static String frobnicateString(String base, int times) {

  // ... etc

  }

  public static void throwIfCondition(boolean condition, String msg) {

  // ... etc

  }

  }

  这些类乍一看挺吸引人的,因为它们里面的这些方法不属于任何一个地方。因此你以代码重用之名将它们全都扔到这里了。

  这么解决问题结果更糟。把它们放回它们原本属于的地方吧,如果你确实有一些类似的常用方法,考虑下Java 8里接口的默认方法。并且由于它们是接口,你可以实现多个方法。

  public interface Thrower {

  public void throwIfCondition(boolean condition, String msg) {

  // ...

  }

  public void throwAorB(Throwable a, Throwable b, boolean throwA) {

  // ...

  }

  }

  这样需要使用它的类只需简单的实现下这个接口就可以了。

  格式

  格式远比许多程序员相像的要重要的多。一致的格式说明你关注自己的代码或者对别人有所帮助?是的。不过你先不要着急为了让代码整齐点而浪费一整天的时间在那给if块加空格了。

  如果你确实需要一份代码格式规范,我强烈推荐Google的Java风格指南。这份指南最精彩的部分就是编程实践这节了。非常值得一读。

  文档

  面向用户的代码编写下文档还是很重要的。这意味着你需要提供一些使用的示例,同时你的变量方法和类名都应该有适当的描述信息。

原文转自:http://it.deepinmind.com/java/2014/05/21/better-java.html