阿里巴巴安卓编码规范Java编码规范,来测测你能得多少分

如何看待阿里招聘java工程师,通过java编码规范认证优先录取? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。30被浏览<strong class="NumberBoard-itemValue" title="分享邀请回答添加评论分享收藏感谢收起51 条评论分享收藏感谢收起为了账号安全,请及时绑定邮箱和手机
点击这里,将文章分享到自己的动态
阿里巴巴2017Java编程规范个人总结(一)
【编程规约】
所有命名不能以美元符和下划线开始和结尾
禁止拼音加英文
类用UserDao..方法,变量,参数用userDao
常量名全部大写,下划线隔开
抽象类使用Abstract或者Base开头,异常类使用Exception结尾
boolean属性命名不能使用is开头
如果使用到了设计模式,建议在类名中体现出具体模式。LoginProxy
接口类中方法不加权限修饰符
接口和实现类 实现类以Impl结尾
MVC各层命名规约
Service/Dao层
获取单个对象 get 前缀
获取多个对象 list 前缀
获取统计值的方法 count 前缀
插入 save 前缀
删除 remove
修改 update
数据对象 DO 是数据表名
数据传输对象 DTO
是业务领域相关的名称
展示对象 VO
是网页名称 使用了模板框架
POJO是 DO DTO BO VO 统称
不允许出现魔法值,未经定义的常量突然出现
Long类型使用大写L结尾
常量类存放常量要分门别类放置
常量的复用层次的安排
跨应用共享常量 :二方库中 通常是client.jar中的constant目录下
应用内共享常量 :一方库的modules中的constant
子工程内共享常量 :当前子工程的constant目录下
包内共享常量:当前包下单独的constant目录下
类内共享常量:直接定义 private static final
小括号,左右括号前后之间没有空格
if/for/while/switch/do 后加空格: 例如 :if ()
任何运算符前后都必须加空格
缩进采用4个空格,而不是tab字符,IDE要调整一下
单行字符不超过120个,超出需换行 第二行比第一行缩进4个空格,第三行以后就和第二行平齐就可以了
运算符与下文一起换行
方法调用的点符号与下文一起换行
调用方法 多个参数,超长,需逗号后进行换行
括号之前不要换行
方法参数在定义和传入时,多个参数逗号后边必须加空格
编码统一采用UTF-8 IDE中换行符采用unix格式
方法体内执行语句组,变量的定义语句组,不同的业务逻辑之间或者不同的语义之间插入一个空行,相同业务逻辑和语义之间不需要插入空行
避免使用对象来引用类的静态变量或方法
所有的覆写方法,必须加注解 @Override
相同参数类型,相同业务含义,才可以使用Java的可变参数避免使用Object
对外暴露的接口签名,原则上不允许修改方法签名,避免对接口调用方法产生影响,接口过时必须加@Deprecated注解,并说明采用的新接口或新服务是什么
不能使用过时的类或方法
使用 "t".equals(test)方式,推荐使用java.util.Object#equals (jdk7引入的工具类)
所有的相同类型的包装类对象之间的值比较,全部使用equals方法,
注意: Integer对象 使用==也可以,但是会产生很多内存浪费
所有的POJO类属性必须使用包装数据类型
RPC方法的返回值和参数必须使用包装数据类型
所有的局部变量 推荐使用基本数据类型
定义 DO/DTO/VO等POJO类时,不要设定任何属性的默认值
序列化类新增属性时,不要修改serialVersionUID字段,避免反序列化失败,如果完全不兼容升级,避免反序列化混乱,可以修改serialVersionUID的值
构造方法不能有任何的业务逻辑,只是用来初始化对象的
POJO类每一个都必须重写 toString方法,方便之后debug
使用索引访问用String 的split 方法得到的数组时,需做最后一个分隔符后有无内容的检查,否则会有下标超出的异常
当一个类有多个构造方法,或者多个重名方法,这些方法应该按顺序放置在一起
类内方法的定义顺序依次是 共有方法或保护方法 -& 私有方法 -& setter/getter方法
setter/getter方法中也不要加入业务逻辑
循环体中的字符串的连接方式,使用StringBuffer的append方法进行扩展
final可提高程序响应效率,声明成final的情况:
不需要重新赋值的变量,包括类属性,局部变量
对象参数前加final,表示不允许修改引用的指向
类方法确定不允许被重写
慎用Object的clone方法来拷贝对象,最好重写该方法,实现属性的拷贝
类成员与方法访问控制从严:
如果不允许外部直接通过new来创建对象,那么构造方法显式声明并private
工具类不允许有public或default构造方法
类非static成员变量并且与子类共享,必须是protexted
类非static成员变量并且仅在本类中使用,必须是private
若是static成员变量,必须考虑是否final
类成员方法只供类内部调用,必须是private
类成员方法只对继承类公开,那么限制为protected
注意 访问范围的严格控制利于对模块解耦,如果删除一个private方法,删除就删除,但是如果是public方法就得手心冒汗的删除了
关于HashCode 和equals的处理
只要重写equals,就必须重写HashCode
因为Set存储的是不重复的对象,依据HashCode和equals进行判断,所以Set存储的方法必须重写这两个方法
如果自定义对象作为Map的键,那么必须重写HashCode和equals
ArrayList的subList结果不可强转成ArrayList,否则会抛出类型强转的错误
subList返回的是ArrayList的内部类,是ArrayList的一个视图,对于subList的所有操作最终都会反映到原列表上
在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、删除均产生 ConcurrentModificationException 异常。
使用集合转数组的方法,必须使用集合的 toArray(T[] array) ,传入的是类型完全一样的数组,大小就是 list . size()
String[] array = new String[list.size()];
array = list.toArray(array);
把数组转换成集合:使用工具类 Arrays . asList()时 ,不能使用其修改集合相关的方法,它的 add / remove / clear 方法会抛出 UnsupportedOperationException 异常。
asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。 Arrays . asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。
String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);
第一种情况: list.add("c");
运行时异常。
第二种情况: str[0]= "gujin"; 那么 list.get(0) 也会随之修改。
泛型通配符&?
extends T &来接收返回的数据,此写法的泛型集合不能使用 add 方法。
说明:苹果装箱后返回一个&?
extends Fruits &对象,此对象就不能往里加任何水果,包括苹果。
不要在 foreach 循环里进行元素的 remove / add 操作。 remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。
List&String& a = new ArrayList&String&();
a.add("1");
a.add("2");
for (String temp : a) {
if("1".equals(temp)){
a.remove(temp);
在 JDK 7 版本以上, Comparator 要满足自反性,传递性,对称性,不然 Arrays . sort ,Collections . sort 会报 IllegalArgumentException 异常。
1 ) 自反性: x , y 的比较结果和 y , x 的比较结果相反。
2 ) 传递性: x & y , y & z ,则 x & z 。
3 ) 对称性: x = y ,则 x , z 比较结果和 y , z 比较结果相同。
集合初始化时,尽量指定集合初始值大小。
使用 entrySet 遍历 Map 类集合 KV ,而不是 keySet 方式进行遍历
keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出key 所对应的 value 。
而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效率更高。
如果是 JDK 8,使用 Map . foreach 方法。
values() 返回的是 V 值集合,是一个 list 集合对象 ;keySet() 返回的是 K 值集合,是一个 Set 集合对象 ;entrySet() 返回的是 K - V 值组合集合。
高度注意 Map 类集合 K / V 能不能存储 null 值的情况,如下表格:
Dictionary
ConcurrentHashMap
AbstractMap
分段锁技术
AbstractMap
线程不安全
AbstractMap
线程不安全
合理利用好集合的有序性 (sort) 和稳定性 (order) ,避免集合的无序性 (unsort) 和不稳定性 (unorder) 带来的负面影响。
稳定性指集合每次遍历的元素次序是一定的。
有序性是指遍历的结果是按某种比较规则依次排列的。
如: ArrayList 是 order / unsort;HashMap 是 unorder / unsort;TreeSet 是order / sort 。
利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的contains 方法进行遍历、对比、去重操作。
获取单例对象需要保证线程安全,其中的方法也要保证线程安全。
资源驱动类、工具类、单例工厂类都需要注意。
创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。
线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
1) FixedThreadPool 和 SingleThreadPool :
允许的请求队列长度为 Integer.MAX_VALUE ,可能会堆积大量的请求,从而导致 OOM 。
2) CachedThreadPool 和 ScheduledThreadPool :
允许的创建线程数量为 Integer.MAX_VALUE ,可能会创建大量的线程,从而导致 OOM 。
SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为static ,必须加锁,或者使用 DateUtils 工具类。
如果是 JDK 8 的应用,可以使用 Instant 代替 Date , LocalDateTime 代替 Calendar ,DateTimeFormatter 代替 Simpledateformatter ,
官方给出的解释: simple beautiful strongimmutable thread - safe 。
高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁 ; 能锁区块,就不要锁整个方法体 ; 能用对象锁,就不要用类锁。
对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。
线程一需要对表 A 、 B 、 C 依次全部加锁后才可以进行更新操作,那么线程二的加锁顺序也必须是 A 、 B 、 C ,否则可能出现死锁。
并发修改同一记录时,避免更新丢失,要么在应用层加锁,要么在缓存加锁,要么在数据库层使用乐观锁,使用 version 作为更新依据。
如果每次访问冲突概率小于 20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于 3 次。
多线程并行处理定时任务时, Timer 运行多个 TimeTask 时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用 ScheduledExecutorService 则没有这个问题。
使用 CountDownLatch 进行异步转同步操作,每个线程退出前必须调用 countDown方法,线程执行代码注意 catch 异常,确保 countDown 方法可以执行,避免主线程无法执行至 countDown 方法,直到超时才返回结果。
注意,子线程抛出异常堆栈,不能在主线程 try - catch 到。
避免 Random 实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降。
Random 实例包括 java . util . Random 的实例或者
Math . random() 实例。
通过双重检查锁 (double - checked locking)( 在并发场景 ) 实现延迟初始化的优化问题隐患
The " Double - Checked Locking is Broken "
Declaration) ,推荐问题解决方案中较为简单一种 ( 适用于 JDK 5 及以上版本 ) ,将目标属性声明为
volatile 型 。
volatile 解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但是如果多写,同样无法解决线程安全问题。如果是 count ++操作,使用如下类实现:
AtomicInteger count =
new AtomicInteger(); count . addAndGet( 1 );
如果是 JDK 8,推荐使用 LongAdder 对象,比 AtomicLong 性能更好 ( 减少乐观锁的重试次数 ) 。
HashMap 在容量不够进行 resize 时由于高并发可能出现死链,导致 CPU 飙升,在开发过程中注意规避此风险。
ThreadLocal 无法解决共享对象的更新问题, ThreadLocal 对象建议使用 static修饰。这个变量是针对一个线程内所有操作共有的,所以设置为静态变量,
所有此类实例共享此静态变量 ,也就是说在类第一次被使用时装载,只分配一块存储空间,所有此类的对象 ( 只要是这个线程内定义的 ) 都可以操控这个变量。
在一个 switch 块内,每个 case 要么通过 break / return 等来终止,要么注释说明程序将继续执行到哪一个 case 为止 ;
在一个 switch 块内,都必须包含一个 default 语句并且放在最后,即使它什么代码也没有。
在 if / else / for / while / do 语句中必须使用大括号,即使只有一行代码
推荐尽量少用 else ,
if - else 的方式可以改写成:
逻辑上超过 3 层的 if-else 代码可以使用卫语句,或者状态模式来实现
除常用方法(如 getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。
boolean existed = (file.open(fileName, "w") != null) && (...) || (...);if (existed) {}
循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据库连接,进行不必要的 try - catch 操作 ( 这个 try - catch 是否可以移至循环体外) 。
接口入参保护,这种场景常见的是用于做批量操作的接口。
方法中需要进行参数校验的场景:
1 ) 调用频次低的方法。
2 ) 执行时间开销很大的方法,参数校验时间几乎可以忽略不计,但如果因为参数错误导致中间执行回退,或者错误,那得不偿失。
3 ) 需要极高稳定性和可用性的方法。
4 ) 对外提供的开放接口,不管是 RPC / API / HTTP 接口。
5) 敏感权限入口。
方法中不需要参数校验的场景:
1 ) 极有可能被循环调用的方法,不建议对参数进行校验。但在方法说明里必须注明外部参数检查。
2 ) 底层的方法调用频度都比较高,一般不校验。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底层才会暴露问题。
一般 DAO 层与 Service层都在同一个应用中,部署在同一台服务器中,所以 DAO 的参数校验,可以省略。
3 ) 被声明成 private 只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参数已经做过检查或者肯定不会有问题,此时可以不校验参数。
类、类属性、类方法的注释必须使用 Javadoc 规范,使用/* 内容 /格式,不得使用 // xxx 方式。
所有的抽象方法 ( 包括接口中的方法 ) 必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
所有的类都必须添加创建者信息。
方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/ /注释,注意与代码对齐。
所有的枚举类型字段必须要有注释,说明每个数据项的用途。
与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持英文原文即可。
代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。
代码与注释更新不同步,就像路网与导航软件更新不同步一样,如果导航软件严重滞后,就失去了导航的意义。
注释掉的代码尽量要配合说明,而不是简单的注释掉。
代码被注释掉有两种可能性:
1 ) 后续会恢复此段代码逻辑。
2 ) 永久不用。
情况(1)如果没有备注信息,难以知晓注释动机。(2)建议直接删掉 ( 代码仓库保存了历史代码 ) 。
对于注释的要求:
第一、能够准确反应设计思想和代码逻辑 ;
第二、能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。
完全没有注释的大段代码对于阅读者形同天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路 ;
注释也是给继任者看的,使其能够快速接替自己的工作。
好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的一个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。
特殊注释标记,请注明标记人与标记时间。注意及时处理这些标记,通过标记扫描,经常清理此类标记。 线上故障有时候就是来源于这些标记处的代码。
1 ) 待办事宜 (TODO) : ( 标记人,标记时间, [ 预计处理时间 ])
表示需要实现,但目前还未实现的功能。这实际上是一个 Javadoc 的标签,目前的 Javadoc还没有实现,但已经被广泛使用。只能应用于类,接口和方法 ( 因为它是一个 Javadoc 标签 ) 。
2 ) 错误,不能工作 (FIXME) : ( 标记人,标记时间, [ 预计处理时间 ])
在注释中用 FIXME 标记某代码是错误的,而且不能工作,需要及时纠正的情况。
在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
不要在方法体内定义: Pattern pattern =
Pattern . compile( 规则 );
velocity 调用 POJO 类的属性时,建议直接使用属性名取值即可,模板引擎会自动按规范调用 POJO 的 getXxx() ,
如果是 boolean 基本数据类型变量 (boolean 命名不需要加 is前缀 ) ,会自动调用 isXxx() 方法。
注意如果是 Boolean 包装类对象,优先调用 getXxx() 的方法。
后台输送给页面的变量必须加 $!{var} ——中间的感叹号。
如果 var = null 或者不存在,那么 ${var} 会直接显示在页面上。
Math . random() 这个方法返回是 double 类型,注意取值的范围 0≤ x &1 ( 能够取到零值,注意除零异常 ) ,
如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法。
获取当前毫秒数 System . currentTimeMillis(); 而不是 new Date() . getTime();
如果想获取更加精确的纳秒级时间值,用 System . nanoTime() 。在 JDK 8 中,针对统计时间等场景,推荐使用 Instant 类。
尽量不要在 vm 中加入变量声明、逻辑运算符,更不要在 vm 模板中加入任何复杂的逻辑。
任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存。
对于“明确停止使用的代码和配置”,如方法、变量、类、配置文件、动态配置属性等要坚决从程序中清理出去,避免造成过多垃圾。
若觉得本文不错,就分享一下吧!
评论加载中...
看过此文的用户,还看了以下文章
正在加载中
作者相关文章如何评价阿里近期发布的Java编码规范? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。<strong class="NumberBoard-itemValue" title="被浏览<strong class="NumberBoard-itemValue" title="1,903分享邀请回答@Test
void 测试提交订单() {
这样JUnit跑出来的结果就都是正统汉字了。再见,恶心的拼写错误(逃(不过我轮岗结束后那些汉语方法名应该又都被干掉了哈哈哈哈)简单说说这段文字的背景:那是2010年的事了。我那个时候在淘宝运营支撑部的平台架构组。我们会偶尔轮岗到别的业务组去体验一下业务组的实际工作状况和需求,以便更好的服务业务组。不敢说轮岗过去能帮上多少忙,不乱帮倒忙就不错了。总之最低限度我们得体会一下业务组到底有哪些需求,有哪些痛点需要解决。有一次我轮岗过去的组里的某些代码确实是让我震惊了。不但有超过一千行的单个方法,没人敢重构,而且还有前面引用的回答说的,“英文、拼错的英文、汉语拼音、拼错的汉语拼音”。确实会有时候一个上层接口的实现调用下层接口的方法,上层可能是getDiscount(),下层却是getDaZhe()…但那块代码并不是我所知道的淘宝的代码的典型状况。从我的角度看,那段代码确实是很不好,但是是个例而不是常态。我当时接触的业务代码不是特别多,平时接触的中间件(例如HSF)和通用服务,还有我自己写的Impla 2.x / 3.x啥的,里面的代码都比较干净,各种命名都比较统一,并没有上面引用的回答所说的情况。我当时只是把JUnit的测试用例里面的用例方法给改成用中文名了。主要是想行为艺术一下提醒那边的同事他们原本的命名实在太糟糕了,顺带演示一下Java源码支持Unicode的好处/用处。如果我记得没错的话,我轮岗结束后没多久,那些被我改成中文名的方法就又被改回用英文了。希望后来他们用的名字是更统一的吧…后来我也有过一次轮岗到业务组参与写业务代码的经历。那次最初的代码里也有过奇怪的英文+拼音的混合物,但很快组里就有老大组织讨论统一了命名,给出了一个参考词汇表来保证大家的命名是一致的。这就比前面提到的那次轮岗的体验好很多。正是因为阿里的Java代码里曾经有过这样的命名混乱的现象,即便它不是常态也是应该警觉和避免的,所以《阿里Java开发手册》里的这一条在这种上下文里就非常合理:请不要曲解我的文字然后引用来说根本不相关的事情。谢谢。70662 条评论分享收藏感谢收起阿里Java高考卷来了,你能得几分?阿里Java高考卷来了,你能得几分?墨书占呈百家号2018高考进行时又是一年高考,此时,高三学子已经走进高考考场,为青春和梦想奋力一搏。高考,可能离你我已经很远了。可你是否依然怀念,那个全情投入的无悔青春?人生每个阶段都会面临不同的“考试”,每一次都值得我们全力以赴。比如现在,在你面前就有一份《阿里技术2018高考Java卷》。访问:https://ks.wjx.top/m/.aspx进入阿里技术高考现场↑↑↑如果你看过《阿里巴巴Java手册》,这份卷子对你小菜一碟。还木有看过?在阿里技术公众号回复“手册”,赶紧下载,抱抱佛脚。考场规则:1、本次考试预计用时3-5分钟,一共11道题,满分120分。2、考试采取开卷形式,参考资料:《阿里巴巴Java手册》3、单个ID可多次提交,仅以首次提交的答案为准。4、交卷截止日期:6月14日阿里妹将在满分童鞋中,随机抽出十位,送出《阿里巴巴Java手册》实体书一本。很多事情,就像高考前的复习一样,虽然充满不确定性,但是只要拼尽全力。或许下一秒就能改变命运,或许下一秒就有奇迹发生。因为相信,所以看见。本文由百家号作者上传并发布,百家号仅提供信息发布平台。文章仅代表作者个人观点,不代表百度立场。未经作者许可,不得转载。墨书占呈百家号最近更新:简介:分享墨书资讯,感受军事点滴。作者最新文章相关文章70662 条评论分享收藏感谢收起pan.baidu.com/s/1o8RSlaa 最后说说规范文档里我不爽的地方:1. 在2017年,网页、wiki、markdown或者说github页面高度发达的今天,不知道为什么阿里没有选择将规范文档放在网页上,而是用PDF文档直接抛出来,让人费解。文档还被加上重重的水印,好似怕别人剽窃里面的内容一样,感觉像是10年前的小农思维。用PDF文件对于后续的文档改进和版本管理都会是大问题。建议做成类似:2. 文档里规定了代码的格式如下:强制: if / for / while 后面都有空格, { 前面要有空格等:但是在文档后续的代码里,这些规范压根没有被遵守(自己打脸?)看来文档的用心程度还要进一步提高呀!3. 文档里建议用4空格缩进。这点之前说过很多次,在硅谷的程序圈差不多10年前已经逐渐从4空格缩进改为2空格缩进,所以国内这一块最好能够与时俱进。主要4空格缩进在稍微逻辑复杂一点的代码里,就直接超过120行的宽度限制了。参考:4. 建议多加上对于 java 8 的支持和说明,同时可以多借鉴guava的一些写法:比如对于array set dictionary 的操作,和 filter map 以及 closeable ,外加java8的 lambda。赞同 41028 条评论分享收藏感谢收起}

我要回帖

更多关于 阿里巴巴安卓编码规范 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信