阿里Java编程规约【三】代码格式

简介: 1. 【强制】如果大括号内为空,简洁地写成{}即可,大括号中间无需换行和空格;如果是非空代码块,则:1)左大括号前不换行。2)左大括号后换行。3)右大括号前换行。

1. 【强制】如果大括号内为空,简洁地写成{}即可,大括号中间无需换行和空格;如果是非空代码块,则:


1)左大括号前不换行。


2)左大括号后换行。


3)右大括号前换行。


4)右大括号后还有 else 等代码则不换行;表示终止的右大括号后必须换行。


2. 【强制】左小括号和右边相邻字符之间不需要空格;右小括号和左边相邻字符之间也不需要空格;而左大 括号前需要加空格。详见第 5 条下方正例提示。


反例:if(空格 a == b 空格)


3. 【强制】if / for / while / switch / do 等保留字与左右括号之间都必须加空格。


4. 【强制】任何二目、三目运算符的左右两边都需要加一个空格。


说明:包括赋值运算符 =、逻辑运算符 &&、加减乘除符号等。


5. 【强制】采用 4 个空格缩进,禁止使用 Tab 字符。


说明:如使用 Tab 缩进,必须设置 1 个 Tab 为 4 个空格。


IDEA 设置 Tab 为 4 个空格时,请勿勾选 Use tab character;

Eclipse 设置中,找到 tab policy 设置为 Spaces only,Tab size:4,最后必须勾选 insert spaces for tabs


正例:(涉及上述中的 1-5 点)

public static void main(String[] args) {
    // 缩进 4 个空格
    String say = "hello";
    // 运算符的左右必须有一个空格
    int flag = 0;
    // 关键词 if 与括号之间必须有一个空格,括号内的 f 与左括号,0 与右括号不需要空格
    if (flag == 0) {
        System.out.println(say);
    }
    // 左大括号前加空格且不换行;左大括号后换行
    if (flag == 1) {
        System.out.println("world");
        // 右大括号前换行,右大括号后有 else,不用换行
    } else {
        System.out.println("ok");
        // 在右大括号后直接结束,则必须换行
    }
}


6. 【强制】注释的双斜线与注释内容之间有且仅有一个空格。


正例:

// 这是示例注释,请注意在双斜线之后有一个空格
String commentString = new String("demo");


7. 【强制】在进行类型强制转换时,右括号与强制转换值之间不需要任何空格隔开。

正例:

double first = 3.2D;
int second = (int)first + 2;


8. 【强制】单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则:


1)第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进,参考示例。


2)运算符与下文一起换行。


3)方法调用的点符号与下文一起换行。


4)方法调用中的多个参数需要换行时,在逗号后进行。


5)在括号前不要换行。


正例:

StringBuilder builder = new StringBuilder();
// 超过 120 个字符的情况下,换行缩进 4 个空格,并且方法前的点号一起换行
builder.append("yang").append("hao")...
    .append("chen")...
    .append("chen")...
    .append("chen");


9.【强制】方法参数在定义和传入时,多个参数逗号后面必须加空格。


正例:下例中实参的 args1 逗号后边必须要有一个空格。

method(args1, args2, args3);


10. 【强制】IDE 的 text file encoding 设置为 UTF-8;IDE 中文件的换行符使用 Unix 格式,不要使用 Windows 格式。


11.【推荐】单个方法的总行数不超过 80 行。


说明:除注释之外的方法签名、左右大括号、方法内代码、空行、回车及任何不可见字符的总行数不超过 80 行。


正例:代码逻辑分清红花和绿叶,个性和共性,绿叶逻辑单独出来成为额外方法,使主干代码更加晰;共性逻辑抽取 成为共性方法,便于复用和维护。


12. 【推荐】没有必要增加若干空格来使变量的赋值等号与上一行对应位置的等号对齐。

正例:

int a = 3;
long b = 4L;
float c = 5F;
StringBuffer sb = new StringBuffer();


说明:在变量比较多的情况下,是 非常累赘的事情。


13. 【推荐】不同逻辑、不同语义、不同业务的代码之间插入一个空行,分隔开来以提升可读性。


说明:任何情形,没有必要插入多个空行进行隔开。


额外加餐



文档注释标签


Java 语言规范还定义了一种特殊的注释,叫文档注释(doc comment),这种注释用于编写代码 API 的文档。


  • 以 /** 开头(不是通常使用的 /*),以 */ 结尾。文档注释放在类型或成员定义的前面,其中的内容是那个类型或成员的文档。


  • 文档注释的描述性内容可以包含简单的 HTML 标记标签,例如:<i> 用于强调,<code> 用于显示类、方法和字段的名称,<pre> 用于显示多行代码示例。除此之外,也可以包含 <p> 标签,把说明分成多个段落;还可以使用 <ul> 和 <li> 等相关标签,显示无序列表等结构。不过,要记住,你编写的内容会嵌入复杂的大型 HTML 文档,因此,文档注释不能包含 HTML 主结构标签,例如 <h2> 和 <hr>,以防影响那个大型 HTML 文档的结构。


  • @author name
    添加一个“Author:”条目,内容是指定的名字。每个类和接口定义都应该使用这个标签,但单个方法和字段一定不能使用。如果一个类有多位作者,在相邻的几行中使用多个 @author 标签。


  • @version text
    插入一个“Version:”条目,内容是指定的文本。例如:
    @version 1.32, 08/26/04
    每个类和接口的文档注释中都应该包含这个标签,但单个方法和字段不能使用。这个标签经常和支持自动排序版本号的版本控制系统一起使用,例如 git、Perforce 或 SVN。


  • @param parameter-name description
    把指定的参数及其说明添加到当前方法的“Parameters:”区域。在方法和构造方法的文档注释中,每个参数都要使用一个 @param 标签列出,而且应该按照参数传入方法的顺序排列。这个标签只能出现在方法或构造方法的文档注释中。


  • @return description
    插入一个“Returns:”区域,内容是指定的说明。每个方法的文档注释中都应该使用这个标签,除非方法返回 void,或者是构造方法。为了保持简短,建议使用句子片段。

@return <code>true</code>:成功插入
        <code>false</code>:列表中已经包含要插入的对象


  • @exception full-classname description
    添加一个“Throws:”条目,内容是指定的异常名称和说明。方法和构造方法的文档注释应该为 throws 子句中的每个已检异常编写一个 @exception 标签。如果方法的用户基于某种原因想捕获当前方法抛出的未检异常(即 RuntimeException 的子类),@exception 标签也可以为这些未检异常编写文档。如果方法能抛出多个异常,要在相邻的几行使用多个 @exception 标签,而且按照异常名称的字母表顺序排列。这个标签只能出现在方法和构造方法的文档注释中。


  • @throws full-classname description
    这个标签是 @exception 标签的别名。


  • @see reference
    添加一个“See Also:”条目,内容是指定的引用。这个标签可以出现在任何文档注释中。


  • @deprecated explanation
    这个标签指明随后的类型或成员弃用了,应该避免使用。javadoc 会在文档中添加一个明显的“Deprecated”条目,内容为指定的 explanation 文本。这个文本应该说明这个类或成员从何时开始弃用,如果可能的话,还要推荐替代的类或成员,并且添加指向替代的类或成员的链接。
    一般情况下,javac 会忽略所有注释,但 @deprecated 标签是个例外。如果文档注释中有这个标签,编译器会在生成的类文件中注明弃用信息,提醒其他类,这个功能已经弃用。


  • @since version
    指明类型或成员何时添加到 API 中。这个标签后面应该跟着版本号或其他形式的版本信息。例如:@since JDK1.0
    每个类型的文档注释都应该包含一个 @since 标签;类型初始版本之后添加的任何成员,都要在其文档注释中加上 @since 标签。


行内文档注释标签


只要能使用 HTML 文本的地方都可以使用行内标签。因为这些标签直接出现在 HTML 文本流中,所以要使用花括号把标签中的内容和周围的 HTML 文本隔开。javadoc 支持的行内标签包括如下几个。


  • {@link reference }
    {@link}标签和 @see标签的作用类似,但 @see 标签是在专门的“See Also:”区域放一个指向引用的链接,而 {@link}标签在行内插入链接。在文档注释中,只要能使用 HTML 文本的地方都可以使用{@link} 标签。
    例如: @param regexp 搜索时使用的正则表达式。这个字符串参数使用的句法必须符合{@link java.util.regex.Pattern}制定的规则。


  • {@linkplain reference }
    {@linkplain}标签和 {@link} 标签的作用类似,不过,在 {@linkplain} 标签生成的链接中,链接文字使用普通的字体,而 {@link} 标签使用代码字体。如果 reference 包含要链接的 feature 和指明链接替代文本的 label,就要使用 {@linkplain} 标签。


  • {@inheritDoc}
    如果一个方法覆盖了超类的方法,或者实现了接口中的方法,那么这个方法的文档注释可以省略一些内容,让 javadoc 自动从被覆盖或被实现的方法中继承。{@inheritDoc} 标签可以继承单个标签的文本,还能在继承的基础上再添加一些说明。继承单个标签的方式如下:

@param index @{inheritDoc}
@return @{inheritDoc}


  • {@docRoot}
    这个行内标签没有参数,javadoc生成文档时会把它替换成文档的根目录。这个标签在引用外部文件的超链接中很有用,例如引用一张图片或者一份版权声明:
    <img src="{@docroot}/images/logo.gif">这份资料受<a href="{@docRoot}/legal.html">版权保护</a>


  • {@literal text }
    这个行内标签按照字面形式显示texttext 中的所有 HTML 都会转义,而且所有javadoc标签都会被忽略。虽然不保留空白格式,但仍适合在 <pre> 标签中使用。


  • {@code text }
    这个标签和 {@literal} 标签的作用类似,但会使用代码字体显示 text 的字面量。


  • {@value}
    没有参数的 {@value} 标签在 static final 字段的文档注释中使用,会被替换成当前字段的常量值。


  • {@value reference }
    这种 {@value}标签的变体有一个reference参数,指向一个static final字段,会被替换成指定字段的常量值。


包的文档注释


  • javadoc 会在包所在的目录(存放包中各个类的源码)中需找一个名为 package.html 的文件,这个文件中的内容就是包的文档。


  • package.html 文件可以包含简单的 HTML 格式文档,也可以使用 @see@link@deprecated@since 标签。因为 package.html 不是 Java 源码文件,所以其中的文档应该是 HTML,而不能是 Java 注释(即不能包含在 /** 和 */ 之间)。最后,在 package.html 文件中,所有 @see@link 标签都必须使用完全限定的类名。


类成员的顺序


这并没有唯一的正确解决方案,但如果都使用一致的顺序将会提高代码的可读性,推荐使用如下排序:

1. 常量
  2. 字段
  3. 构造函数
  4. 重写函数和回调
  5. 公有函数
  6. 私有函数
  7. 内部类或接口


举例如下:

public class MainActivity extends Activity {
    private static final String TAG = MainActivity.class.getSimpleName();
    private String mTitle;
    private TextView mTextViewTitle;
    @Override
    public void onCreate() {
        ...
    }
    public void setTitle(String title) {
        mTitle = title;
    }
    private void setUpView() {
        ...
    }
    static class AnInnerClass {
    }
}


如果类继承于 Android 组件(例如 Activity 或 Fragment),那么把重写函数按照他们的生命周期进行排序是一个非常好的习惯,例如,Activity 实现了 onCreate()、onDestroy()、onPause()、onResume(),它的正确排序如下所示:

public class MainActivity extends Activity {
    // Order matches Activity lifecycle
    @Override
    public void onCreate() {...}
    @Override
    public void onResume() {...}
    @Override
    public void onPause() {...}
    @Override
    public void onDestroy() {...}
}


参考



  1. 2022 Java开发手册(黄山版).pdf


  1. Android 开发规范(完结版) | Blankj's Blog


https://blankj.com/2017/03/08/android-standard-dev-final/




目录
相关文章
|
1月前
|
Java 程序员
Java编程中的异常处理:从基础到高级
在Java的世界中,异常处理是代码健壮性的守护神。本文将带你从异常的基本概念出发,逐步深入到高级用法,探索如何优雅地处理程序中的错误和异常情况。通过实际案例,我们将一起学习如何编写更可靠、更易于维护的Java代码。准备好了吗?让我们一起踏上这段旅程,解锁Java异常处理的秘密!
|
13天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
17天前
|
算法 Java 调度
java并发编程中Monitor里的waitSet和EntryList都是做什么的
在Java并发编程中,Monitor内部包含两个重要队列:等待集(Wait Set)和入口列表(Entry List)。Wait Set用于线程的条件等待和协作,线程调用`wait()`后进入此集合,通过`notify()`或`notifyAll()`唤醒。Entry List则管理锁的竞争,未能获取锁的线程在此排队,等待锁释放后重新竞争。理解两者区别有助于设计高效的多线程程序。 - **Wait Set**:线程调用`wait()`后进入,等待条件满足被唤醒,需重新竞争锁。 - **Entry List**:多个线程竞争锁时,未获锁的线程在此排队,等待锁释放后获取锁继续执行。
50 12
|
13天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
35 3
|
13天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
93 2
|
20天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
56 2
|
30天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
30天前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
50 3
|
1月前
|
安全 Java API
Java中的Lambda表达式:简化代码的现代魔法
在Java 8的发布中,Lambda表达式的引入无疑是一场编程范式的革命。它不仅让代码变得更加简洁,还使得函数式编程在Java中成为可能。本文将深入探讨Lambda表达式如何改变我们编写和维护Java代码的方式,以及它是如何提升我们编码效率的。
|
11天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者