Effective Java for Android

原文地址:https://medium.com/rocknnull/effective-java-for-android-cheatsheet-bf4e3433889a#.ksxu4xb86

《Effective Java》被认为是关于编写可维护的稳定且有效Java代码的最重要的书籍之一。Android使用的是Java,这就意味着所有书中所有的建议都适用,对吗?不一定。一些人认为大多数书中的建议都不适用于Android的开发环境。在我看来,事情并非如此。我相信书中的部分内容是不适用的,毕竟不是所有的Java特性都在Android中得到了充分利用(比如enums, serialization等),或者是因为移动设备的限制(比如:Dalvik/ART就和JVM不同)。无论如何,大多数书中的范例可以小幅或不用修改即可使用,并且可以变的更加健壮,简洁,更加可维护。

这篇文章会集中阐述我认为在开发Android app时,书中最重要的部分。对于那些读过此书的人,这篇文章会让你回忆起书中提到的内容或原则。对于还未阅读过的人来说,这可以让他们了解此书所提供的内容。

强制不可实例化
如果你不想让对象可以通过新的关键字创建,那么强制它使用一个私有的构造函数。
对于只包含静态方法的工具类来讲格外有用。

class MovieUtils {
    private MovieUtils() {}
    static String titleAndYear(Movie movie) {
        [...]
    } 
}

静态工厂
替代使用新关键字,构造函数使用静态工厂方法(和一个私有构造函数)。

class Movie {
    [...]
    public static Movie create(String title) {
        return new Movie(title);
    } 
}

创建者
当你的对象需要三个以上构造函数参数时,使用创建者来构建对象。它书写起来可能会有一点冗长,但是它可扩,可读性好。如果你在创建值类,考虑下自动值。

class Movie {
    static Builder newBuilder() {
        return new Builder();
    }
    static class Builder {
        String title;
        Builder withTitle(String title) {
            this.title = title;
            return this;
        }
        Movie build() {
            return new Movie(title);
        }
    }

    private Movie(String title) {
    [...]    
    }
}
// Use like this:
Movie matrix = Movie.newBuilder().withTitle("The Matrix").build();

避免易变
不可变是一个对象在它的整个生命周期内保持相同。所有对象必要的数据在它创建时就被提供。这种方式有许多的优点,比如简单,线程安全和可分享。

class Movie {
    [...]
    Movie sequel() {
        return Movie.create(this.title + " 2");
    } 
} 
// Use like this: 
Movie toyStory = Movie.create("Toy Story"); 
Movie toyStory2 = toyStory.sequel();

让所有类不可变可能会很困难。如果可以,尽量让你的类不可变(比如,private final字段和final类)。对象的创建在手机上更加花费资源,因此不要过度使用。

静态成员类
如果你定义了一个不依赖外部类的内部类,不要忘了将它定成了静态类。

class Movie {
    [...]
    static class MovieAward {
        [...]
    }
}

(几乎)无处不在的泛型
Java是类型安全的,我们需要感谢这一点(看看JS)。尽可能的避免使用不确定的类型或Object类型。大多数时候,泛型的提供令你的代码在编译时是类型安全的。

// DON'T  
List movies = Lists.newArrayList();  
movies.add("Hello!"); 
[...]  
String movie = (String) movies.get(0);

// DO  
List<String> movies = Lists.newArrayList(); 
movies.add("Hello!"); 
[...]  
String movie = movies.get(0);

不要忘了你可以在你的方法和返回值中使用泛型。

// DON'T  List sort(List input) {
    [...] 
}

// DO  <T> List<T> sort(List<T> input) {
    [...] 
}

想要更加灵活,你可以使用通配符来扩展你可以接受的类型范围。

// Read stuff from collection - use "extends" 
void readList(List<? extends Movie> movieList) {
    for (Movie movie : movieList) {
        System.out.print(movie.getTitle());
        [...]
    } 
}

// Write stuff to collection - use "super" 
void writeList(List<? super Movie> movieList) {
    movieList.add(Movie.create("Se7en"));
    [...] 
}

返回空
当我们返回一个列表或集合时,使用无结果而非null。返回一个空集合使得接口更简单(不需要文档或注释null返回方法),并且避免了空指针异常。最好是返回相同的空集合而非创建一个新的。

List<Movie> latestMovies() {
    if (db.query().isEmpty()) {
        return Collections.emptyList();
    }
    [...] 
}

不要加字符串
必须要连接多个字符串,+操作符可能可以。但永远不要使用它来连接大量字符串;性能会非常差。最好使用StringBuilder来替代。

String latestMovieOneLiner(List<Movie> movies) {
    StringBuilder sb = new StringBuilder();
    for (Movie movie : movies) {
        sb.append(movie);
    }
    return sb.toString(); 
}

回收异常
我不赞成用抛出异常来表明错误,但是如果你这么做了,确保异常经过检查,并且异常的接收者可以回收这些错误。

List<Movie> latestMovies() throws MoviesNotFoundException {
    if (db.query().isEmpty()) {
        throw new MoviesNotFoundException();
    }
    [...] 
}

结尾
这个列表并不是书中所提及的全部建议列表,短短的文字也不能充分的解释。这更像是一个实用技巧的小抄。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值