>>分享Java编程技术,对《Java面向对象编程》等书籍提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 24323 个阅读者 刷新本主题
 * 贴子主题:  从 Effective Java 总结一些有助安卓开发的建议 回复文章 点赞(0)  收藏  
作者:Jacky    发表时间:2019-03-03 08:51:32     消息  查看  搜索  好友  邮件  复制  引用

在编写长期运行下既易于维护又能保持高效的 Java 代码这方面 ,《 Effective Java 》被很多人看做最重要的书之一。 Android 使用的是 Java 语言,这就意味着这本书中所有给出的建议一定都是适用与 Android 的,对吗?答案是:不一定。有些人认为这本书给出的大多数建议都不适用于 Android 开发。在我看来,也并非如此。我认为这本书中有一部分是不适用的,因为不是所有的 Java 特性都是为了用于 Android 而优化的(比如枚举,序列化等等),也因为移动设备存在自身的限制(比如 Dalvik/ART 表现和 JVM 不同)。尽管如此,这本书中的大多数范例还是能够不加修改或者少量修改地被使用,并能够有助于建立一个更加健康、干净和可维护的代码库。

本文关注于这本书中我认为对于 Android 开发至关重要的知识点。对于阅读过这本书的人来说,本文可以作为书中提到的原则/知识的回顾。对于那些(目前)还没有读过的人来说,本文可以给他们一个机会去尝试下这本书。

强制不可实例化
如果你不希望使用 new 关键字来创建一个对象,那就强制使用私有构造器(private constructor)。这对于仅包含静态方法的工具类来说更加有用。

List<Movie> latestMovies() {
    if (db.query().isEmpty()) {
        return <strong>Collections.<em>emptyList</em>()</strong>;
    }
    [...]
}
静态工厂
不要使用 _new_ 关键字和构造器,使用静态工厂方法(以及一个私有的构造器)。这些工厂方法是命名的,不需要每次都返回一个新的对象实例,而且可以根据需要返回不同的子类型。

class Movie {
    [...]
    public static Movie <strong>create</strong>(String title) {
        return new Movie(title);
    }
}
【更新】读者 @ stsdema28 提出了一个有用的建议:使用静态工厂会使得测试变得困难。如果这样的话,不妨考虑使用一个非静态的工厂用于在测试时进行模拟(或者一个能够实现的工厂接口)。

Builders
当你有需要三个以上的构造参数时,使用 Builder 去构造这个对象。写起来可能有点啰嗦但是这样伸缩性和可读性都很好。如果你创建的是值类型,考虑 AutoValue。

class Movie {
    static Builder newBuilder() {
        return new Builder();
    }
    static class <strong>Builder</strong> {
        String title;
        Builder <strong>withTitle</strong>(String title) {
            this.title = title;
            return this;
        }
        Movie <strong>build</strong>() {
            return new Movie(title);
        }
    }
    private Movie(String title) {
    [...]
    }
}
// Use like this:
Movie matrix = Movie.<em>newBuilder</em>().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 {
    [...]
    <strong>static</strong> class MovieAward {
        [...]
    }
}
泛型(几乎)无处不在
Java 提供了类型安全的特性,我们应对此心怀感激(看看JS吧)。尽量避免使用原始类型 (raw types)或者对象类型。泛型大多数情况下都提供了让你的代码在编译时类型安全的机制。

// DON'T
List movies = Lists.newArrayList();
movies.add("Hello!");
[...]
String movie = (<strong>String</strong>) movies.get(0);
// Do List
<<strong>String</strong>> 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) {
    [...]
}
为了更加灵活你可以使用 bounded wildcards 来拓展可接受的类型的范围。

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

// Write stuff to collection - use "super"
void writeList(List<? <strong>super</strong> Movie> movieList) {
    movieList.add(Movie.create("Se7en"));
    [...]
}
返回空(列表/集合)
当必须返回空的列表/集合时,避免使用null。返回一个空的集合会产生一个更简单的接口(不需要去进行文档注释并声明函数返回值为 null),还能避免意外的空指针异常。最好返回一个相同的空集合而不是创建一个新的。

List<Movie> latestMovies() {
    if (db.query().isEmpty()) {
        return <strong>Collections.<em>emptyList</em>()</strong>;
    }
    [...]
}
不要用 + 连接 String
如果要连接几个字符串,+ 操作符或许可以。但永远不要使用它来进行大量的字符串连接,那样性能会十分糟糕。最好使用 StringBuilder 来代替。

String latestMovieOneLiner(List<Movie> movies) {
    <strong>StringBuilder</strong> sb = new StringBuilder();
    for (Movie movie : movies) {
        sb.<strong>append</strong>(movie);
    }
    return sb.<strong>toString</strong>();
}
可恢复的异常
我不喜欢通过抛出异常来指明错误,但如果你这样做的话,就要确保异常被检查并且异常的捕获者能够从错误中恢复。

List<Movie> latestMovies() <strong>throws</strong> MoviesNotFoundException {
    if (db.query().isEmpty()) {
        <strong>throw</strong> new MoviesNotFoundException();
    }
    [...]
}
总结
列举的这些不是这本书中所给出的完整建议,也不是简短说明深入评价。只是这些有用的建议的一纸小抄而已。

转自:http://www.importnew.com/25444.html


程序猿的技术大观园:www.javathinker.net
网站系统异常


系统异常信息
Request URL: http://www.javathinker.net/WEB-INF/lybbs/jsp/topic.jsp?postID=674

java.lang.NullPointerException

如果你不知道错误发生的原因,请把上面完整的信息提交给本站管理人员