原文链接 http://source.android.com/source/code-style.html

译文(部分)

开发者编码风格

以上的编码风格都是很严格的规则,而不仅仅只是指导建议。一般来说,不按这些规矩来编码的话,Android是不接受这样的代码的。我们已经发现了现在的有些代码并不是完全按这些规则来的,但是我们还是希望以后的代码可以遵守这些规则。

跟Java语言相关的规则

Android遵循标准的Java编码传统,此外还有以下额外的规则。

不要无视“异常”(Exceptions)

完全无视异常的编码风格好像挺诱人的,比如像这样:

void setServerPort(String value) {    try {        serverPort = Integer.parseInt(value);    } catch (NumberFormatException e) { }}

不要这样写。虽然你可能认为你的代码不会碰到这种错误的情况,或者说你觉得这个异常不重要,不值得处理,但是像上面那样无视异常的话,就会给以后使用你代码的人埋下隐患。你得规规矩矩地在你的代码里处理好每个异常。当然,具体的异常要具体处理。

一看到谁写了空的catch语句,你应该都会有一种毛骨悚然的感觉。当然,肯定有时候你是确实该这么做,但至少你得好好考虑考虑啊。反正在Java里面,像你这么写catch语句,难免会让人感觉毛骨悚然的。 -James Gosling

这么写才可以接受(按优先级排序):

  • 把异常抛给调用你方法的语句
void setServerPort(String value) throws NumberFormatException {    serverPort = Integer.parseInt(value);}
  • 抛一个跟你的代码逻辑抽象程度相对应的异常
void setServerPort(String value) throws ConfigurationException {    try {        serverPort = Integer.parseInt(value);    } catch (NumberFormatException e) {        throw new ConfigurationException("Port " + value + " is not valid.");    }}
  • 优雅地处理异常并且在catch{}语句块里面将出现异常的变量替换成一个恰当的值
/** Set port. If value is not a valid number, 80 is substituted. */void setServerPort(String value) {    try {        serverPort = Integer.parseInt(value);    } catch (NumberFormatException e) {        serverPort = 80;  // 服务器的默认端口    }}
  • 捕获这个异常然后抛出一个新的RuntimeException。其实这是比较危险的。所以说,只有当你非常确定,异常一旦出现,要是不抛出一个RuntimeException程序就只能挂掉的时候,才采用这种方式。
/** 设置端口. 如果值不是一个合法的数字的话, 程序就挂了. */void setServerPort(String value) {    try {        serverPort = Integer.parseInt(value);    } catch (NumberFormatException e) {        throw new RuntimeException("port " + value " is invalid, ", e);    }}

注意:这个原始的异常会传到RuntimeException的构造器。如果你的代码必须得在Java 1.3环境下编译的话,你就必须得忽略掉那个异常。

  • 最后一点,如果你真的很自信,觉得应当无视这个异常,那你可以无视,但你也得
    注释一下你为什么觉得真的可以无视这个异常:
/** 如果值不是一个合法的数字, 就用原始的端口号. */void setServerPort(String value) {    try {        serverPort = Integer.parseInt(value);    } catch (NumberFormatException e) {        // Method is documented to just ignore invalid user input.(译者注:这句能力有限实在不敢译)        // serverPort will just be unchanged.(serverPort不变)    }}

别捕获通用异常(Exception)

捕获异常的时候,很容易偷懒,像这么写:

try {    someComplicatedIOFunction();        // 有抛出IOException的可能    someComplicatedParsingFunction();   // 有抛出ParsingException的可能    someComplicatedSecurityFunction();  // 有抛出SecurityException的可能    // 哟, 一直这么写} catch (Exception e) {    handleError();                      // 我就这样用一个通用的Handler来捕获所有的异常吧}

别这么写。绝大部分情况下捕获通用Exceptions或者Throwable(还是别说Throwable吧因为Throwable也包括Error这种异常)。这样写很危险的,因为这样写意味着你意想不到的异常(比如像ClassCastException这样的RuntimeExceptions)容易在应用级的错误处理中出现问题。这样写的话,会让你的代码不容易进行异常处理,因为这意味着如果有人在你调用的代码里面加一种新的异常,编译器并不会帮你认识到你需要有区别地处理这个新增的异常。大多数情况下,你不应该以同样的方式处理不同类型的异常。

上述这种规则的一种例外的情况就是,测试代码和最外层的代码。你想在这里捕获各种异常(以避免它们出现在UI中,或者要保持一批任务的运行)。在这种情况下,你可以捕获通用Exception(或者Throwable),然后恰当地处理这些异常。即便这样,写之前也得想好,然后在注释里面写清楚为什么在这里这么写是安全的。

“捕获通用异常”的替代方式:
- 一个try语句后面接一个catch语句分别捕获每种不同的异常。这样做可能有点尴尬,但总比捕获所有的异常要好。谨防在catch块里面重复太多代码。
- 用多个try语句块来重构你的代码,使你的代码能有更精细的异常处理。从“解析”里面将IO操作分出来,在各种情况下分开处理异常。
- 重新抛出这个异常。很多情况下,你并不需要捕获这种级别的异常,那就
直接让方法抛出这个异常就行了。

记住:异常是你的朋友。当编译器抱怨你没有捕获异常的时候,别不耐烦,微笑面对吧,编译器这样做只是为了方便你捕获你代码运行时的问题啦!

别用Finalizers(译者注:这个词感觉不好译,不过开发者应该懂)

Finalizers是一种,当一个对象被垃圾回收的时候,执行一块代码的方式。虽然这种方式可能对于清理工作很实用(尤其是对于外部资源来说,根本不能保证finalizer什么时候被调用,或者finalizer到底会不会被调用)。

Android不用finalizers。大多数情况下,你可以用良好的异常处理代码来代替你想在finalizer里面写的代码。如果你真的需要finalizer,那就定义一个close()之类的方法,然后用文档写清楚那个方法什么时候需要被调用(参看InputStream)。在你真的要用finalizer的情况下,如果不要求打印所有详细log消息的话,那就在finalizer中打印出一个简短的log消息吧。

使用完整的“引入”

当你想从foo这个包里面引入Bar这个类时,你有两种方法引入:
- import foo.*;
这样写能潜在地减少import语句的数量。
- import foo.Bar;
写明白到底哪些类是实际用到的,这样写对代码的维护者来说更易读一些。

将缩略语当做单词处理

在给变量,方法,类命名的时候将大写的缩略语作为单词对待,使这些名字更易读:

Good Bad
XmlHttpRequest XMLHTTPRequest
getCustomerId getCustomerID
class Html class HTML
String url String URL
long id long ID

鉴于JDK和Android代码库都对缩略语的处理很不一致,实际上和周围的代码保持一致简直是不可能的事。因此,就把缩略语当做单词对待吧。

使用TODO注释

对于暂时的、短期的解决方式,或者足够好但是并不完美的代码时,使用TODO注释。这些TODO注释应该在所有注释语句后面加上TODO这个字符串,并跟上一个冒号:

// TODO: Remove this code after the UrlTable2 has been checked in.

以及

// TODO: Change this to use a flag instead of a constant.

如果你的TODO语句属性这种形式:“在未来某个时候做某事”,那就确保你会注明一个非常明确的日期(“2005年11月搞定”)或者是一个非常明确的事件(“等所有production mixers理解V7协议之后去掉这段代码”)。

要前后一致

我们的告别语:要前后一致。如果你正在编辑代码,那就花几分钟先看看这句代码周围的代码。然后,再决定这句代码应该用什么样的风格。如果那句代码在if语句周围用的是空格,那你也应该这么做。如果代码的注释有星星,那就让你的注释里也加几个星星咯。
有编码风格指导的重点是要有共同的用于编码的词汇,这样大家就可以专注于说什么,而不是怎么说了。我们把这些通用的编码风格规则放在这里的目的就是要让大家知道这些编码用的词汇,但是局部的风格也挺重要的。如果你加到一个文件中的代码跟它周围的已有代码完全不同,那就打乱了那些你的代码读者在阅读你代码时的节奏了。

Javatests编码风格规则

遵循测试代码命名传统,然后在测试什么和特定的被测试的实例(case)之间用一个下划线来分隔开。这个风格更容易看清楚到底测试什么实例(case)。比如:

testMethod_specificCase1 testMethod_specificCase2void testIsDistinguishable_protanopia() {    ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)    assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))    assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))}

原文链接:http://source.android.com/source/code-style.html

更多相关文章

  1. Android设置中“强行停止”详解
  2. andorid - NDK 编译mips-platform代码
  3. ShareSDK for Android(安卓)只有新浪微博分享
  4. Android下编译库文件jar包并在应用中调用
  5. 【Android(安卓)XML】Android(安卓)XML 转 Java Code 系列之 sty
  6. 那两年炼就的Android内功修养
  7. Android(安卓)Kernel Porting 的简单总结文档
  8. [Android]ListView性能优化之视图缓存(android.widget.ListView)
  9. Android中用Kotlin Coroutine(协程)和Retrofit进行网络请求和取

随机推荐

  1. Android(安卓)应用图标
  2. Android:关于onConfigurationChanged()的
  3. 【Android(安卓)Developers Training】 4
  4. Android(安卓)Material Design 之 Coordi
  5. Android(安卓)如何获取SDCard 内存(二)
  6. Android(安卓)创建文件路径这件事,你也可
  7. Android开发插件的下载与安装
  8. python服务器与android客户端socket通信
  9. Android麦克风录音的实现
  10. Android(安卓)studio中关于Spinner下拉列