Android编码规范风格指导(翻译)

来源:互联网 发布:eview触摸屏软件 编辑:程序博客网 时间:2024/05/16 15:57
原文地址:http://source.android.com/source/code-style.html

有很多为Android开源社区贡献代码的程序员,每个人都有不同的代码风格,为此google出了官方的代码规范,供贡献者的参考。本文为其中文翻译。

下面的这些既不是指导也不是建议,而是实实在在严格的规则,Android开源社区贡献者的代码如果不遵守这些规则,将不会被收录。

并不是所有的代码都遵循下面的规则,但是希望新书写的代码都如此。

1、不要忽略对异常的处理
有些时候,代码似乎忽略了对异常的处理:
void setServerPort(String value) {    try {        serverPort = Integer.parseInt(value);    } catch (NumberFormatException e) { }}

尽管你认为你的代码用于不会遇到抛出异常的错误或者对其处理并不重要,但是请千万别这么做。忽略对异常的处理,就好像在哪一天会被别人浏览的代码里埋下了地雷。你必须对每个异常根据具体的情况做出原则上的处理。

Java语言的联合创始人James Gosling曾经说过,任何时候哪个人写了对异常空处理的程序,都应该感到不寒而栗。而在这个时候,恰恰需要我们做出正确的事,至少你也应该考虑过。在Java中,程序员永远不能逃离不寒而栗的感觉。

可供接受的选择如下所示:
  • 在调用函数后面加上异常判断:
  • 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.");    }}
  • 优雅的处理异常,重新赋值
  • /** 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;  // default port for server     }}
  • 抛出运行时异常,这是一个非常危险的操作,除非你确认唯一正确合适的事就是崩溃程序。
/** Set port. If value is not a valid number, die. */void setServerPort(String value) {    try {        serverPort = Integer.parseInt(value);    } catch (NumberFormatException e) {        throw new RuntimeException("port " + value " is invalid, ", e);    }}
需要记录好异常以及传递给了运行时异常的构造方法,如果您必须在Java1.3版本下编译,旧的异常将被抛弃
  • 如果您实在不需要处理,您也需要在此处加上说明
  • /** If value is not a valid number, original port number is used. */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.    }}

2、不要抓取通用的异常
有些时候,一些懒惰的程序员像如下的格式抓取异常:
try {    someComplicatedIOFunction();        // may throw IOException     someComplicatedParsingFunction();   // may throw ParsingException     someComplicatedSecurityFunction();  // may throw SecurityException     // phew, made it all the way } catch (Exception e) {                 // I'll just catch all exceptions     handleError();                      // with one generic handler!}

你不应该这样做。在所有的案例中,抓却通用的异常和错误超类都是不合适的,尤其是错误超类,因为错误超类还包括了错误Error,这是十分危险的举动。这意味着你不能将一些你永远都不回预期的异常,包括运行时的异常当做普通应用级别的错误处理。它掩盖了合理处理代码不会发生的错误。即使某人加入了新的自定义异常,编译器也不会提醒你区处理。所以在所有的代码中,你都不应该把所以的异常都统一用通用的异常处理。

3、不要自己使用Java的Finalizer回收资源
我们不推荐使用Java的finalize()方法,你能得到在异常中你需要在Finalizer中执行的处理。即使你绝对需要,也应该使用close()方法或者类似的方法,当Finalizer的方法被调用时。

4、完整的导入名
推荐使用完成的导入名,比如import foo.*是没有import foo.Bar好的。

5、在代码前加上标准的说明
每个文件都应该在顶部有个标准的说明
/* * Copyright (C) 2013 The Android Open Source Project  * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at  * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and  * limitations under the License. */package com.android.internal.foo;import android.os.Blah;import android.view.Yada;import java.sql.ResultSet;import java.sql.SQLException;/** * Does X and Y and provides an abstraction for Z. */public class Foo {    ...}
 
每个类或者方法前也需要加上相应的说明:
比如:
/** Returns the correctly rounded positive square root of a double value. */static double sqrt(double a) {    ...}
或者
/** * Constructs a new String by converting the specified array of  * bytes using the platform's default character encoding. */public String(byte[] bytes) {    ...}

7、编写尽量短小的方法
为了代码的变通性,尽量让方法短小用途专一。考虑到有的方法的长度确实很长,所以对方法的长度并没有硬性的标准。当方法的长度达到40行时,请考虑下是否可以优化。

8、Field定义在标准的位置
Field定义在文件顶部,或者需要使用它的方法前面。

9、限制变量的作用域
变量的作用域应控制在最小的范围,只有这样,才能提高代码的可读性、可维护性减少相似的错误。

10、给导入的包排列
  • Android的包
  • 第三方的包
  • java和javax

11、使用空格缩行
     使用4个空格代替Tab,在不同的编译环境中,Tab所表示的长度不一致。

12、符合命名规则
  • 非public和非static的变量名以m开头
  • static变量以s开头
  • 其他变量的开头为小写的单词
  • public和static的变量全部大写
public class MyClass {    public static final int SOME_CONSTANT = 42;    public int publicField;    private static MyClass sSingleton;    int mPackagePrivate;    private int mPrivate;    protected int mProtected;}

13、正确使用大括号
左大括号紧跟代码,不另起一行。
class MyClass {    int func() {        if (something) {            // ...        } else if (somethingElse) {            // ...        } else {            // ...        }    }}

14、空值行的长度
行的长度控制在100个单词以内。

15、使用正确的Java注解(Annotations)
在修饰符之前使用。有些简单的标记型的注解,能够和代码保持在一行。如果有多条注解,每条注解占用一行,
  • @Deprecated: 当方法不在被推荐使用时,将使用此注解。
  • @Override: 当重写父类的方法时,使用此注解
  • @SuppressWarnings:  批注允许您选择性地取消特定代码段(即,类或方法)中的警告。其中的想法是当您看到警告时,您将调查它,如果您确定它不是问题,您就可以添加一个 @SuppressWarnings 批注,以使您不会再看到警告。虽然它听起来似乎会屏蔽潜在的错误,但实际上它将提高代码安全性,因为它将防止您对警告无动于衷 — 您看到的每一个警告都将值得注意。

16、缩写或省略按正常变量命名

17、使用To do的注释

18、节约使用Log
当使用Log的时候,对App的表现有负面的影响,同时也会降低简洁性。

19、代码风格连贯性
如果您正在修改代码,建议花几分钟时间浏览下周围的代码并熟悉下编码风格。在您的代码中,做到一致。

20、测试方法命名
在测试的方法中命名体现出测试了什么方面的内容。
比如:
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))
}




0 0
原创粉丝点击