Android应用Java开发规范

news2024/9/22 20:01:48
  1. 常规编程
    1. 魔法值与魔法数字

1.【强制】不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。

反例: // 开发者 A 定义了缓存的 key。

String key = "Id#taobao_" + tradeId;

cache.put(key, value);

// 开发者 B 使用缓存时直接复制少了下划线,即 key 是"Id#taobao" + tradeId,导致出现故障。

String key = "Id#taobao" + tradeId; cache.get(key);

2.【强制】不允许任何魔法数字(即未经预先定义的常量)直接出现在代码中。

反例:// 开发者 A 在switch case分支直接进行处理

switch (msg.what) {

    case 1:

case 2:

case 3:

case 4:

//此时开发者B接手是一脸懵逼或者说开发者A一周后继续看自己的这代码也是懵逼的

3. 【推荐】不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护。、

说明:大而全的常量类,杂乱无章,使用查找功能才能定位到要修改的常量,不利于理解,也不利于维护。

正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 SystemConfigConsts 下。

    1. 覆盖方法

【强制】所有的覆写方法,必须加 @Override 注解。

说明:getObject() 与 get0bject() 的问题。一个是字母的 O,一个是数字的 0,加 @Override 可以准确判断是否覆盖成功。另外,如果在抽象类中对方法签名进行修改,其实现类会马上编译报错。

    1. equals 方法

【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。

正例:"test".equals(param);

反例:param.equals("test");

说明:推荐使用 JDK7 引入的工具类 java.util.Objects#equals(Object a, Object b)

    1. String、StringBuilder、StringBuffer

【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。

反例: String str = "start";

for (int i = 0; i < 100; i++) {

str = str + "hello";

}

多线程中则推荐StringBuffer,是线程安全的

    1. 集合处理

.【强制】判断所有集合内部的元素是否为空,使用 isEmpty() 方法,而不是 size() == 0 的方式。

说明:在某些集合中,前者的时间复杂度为 O(1),而且可读性更好。

正例:

Map map = new HashMap<>(16);

if (map.isEmpty()) {

}

    1. 循环处理

【强制】不要在 foreach 循环里进行元素的 remove / add 操作。remove 元素请使用 iterator 方式, 如果并发操作,需要对 iterator 对象加锁。

正例:

List list = new ArrayList<>();

list.add("1");

list.add("2");

Iterator iterator = list.iterator();

while (iterator.hasNext()) {

String item = iterator.next();

if (删除元素的条件) {

iterator.remove();

}

}

反例:

for (String item : list) {

if ("1".equals(item)) {

list.remove(item);

}

}

说明:反例中的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”会是同样的结果吗?

  1. 防止NPE产生

【强制】对于所有未知来源的数据都进行null判断,防止NPE产生

  1. 并发操作
    1. 单例对象

【强制】获取单例对象需要保证线程安全,其中的方法也要保证线程安全。

说明:资源驱动类、工具类、单例工厂类都需要注意。

    1. 线程池
      1. 不允许自己创建线程

【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

说明:线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。

      1. 线程池不允许使用 Executors 去创建

【不推荐】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方 式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

说明:Executors 返回的线程池对象的弊端如下:

  1. FixedThreadPool 和 SingleThreadPool:

允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。

  1. CachedThreadPool:

允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

  1. ScheduledThreadPool:

允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。

      1. 线程池命名

【推荐】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。

正例:自定义线程工厂,并且根据外部特征进行分组,比如,来自同一机房的调用,把机房编号赋值给 whatFeatureOfGroup:

public class UserThreadFactory implements ThreadFactory {

private final String namePrefix;

private final AtomicInteger nextId = new AtomicInteger(1);

// 定义线程组名称,在利用jstack 来排查问题时,非常有帮助

UserThreadFactory(String whatFeatureOfGroup) {

namePrefix = "FromUserThreadFactory's" + whatFeatureOfGroup + "-Worker-";

}

@Override

public Thread newThread(Runnable task) {

String name = namePrefix + nextId.getAndIncrement();

Thread thread = new Thread(null, task, name, 0, false);

Log.i(TAG,thread.getName());

return thread;

}

}

      1. 锁的范围

【强制】高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁。

说明:尽可能使加锁的代码块工作量尽可能的小,避免在锁代码块中调用RPC 方法。

      1. 并发修改同一记录

【强制】并发修改同一记录时,避免更新丢失,需要加锁。应用层一般使用volatile或者AtomicXXX

      1. 多线程++等类似非原子操作

【参考】volatile 解决多线程内存不可见问题对于一写多读,是可以解决变量同步问题,但是如果多写,同样无法解决线程安全问题。

说明:如果是count++操作,使用如下类实现:

AtomicInteger count = new AtomicInteger();

count.addAndGet(1);

如果是JDK8,推荐使用LongAdder 对象,比AtomicLong 性能更好(减少乐观锁的重试次数)。

  1. 控制语句
    1. default语句

【推荐】在一个switch 块内,每个case 要么通过continue / break / return 等来终止,要么注释说明程序将继续执行到哪一个case 为止;在一个switch 块内,都必须包含一个default 语句并且放在最后,并且最好进行一定的处理。

说明:注意break 是退出switch 语句块,而return 是退出方法体。

    1. 注意switch外部参数

【强制】当switch 括号内的变量类型为String 并且此变量为外部参数时,必须先进行null 判断。

反例:如下的代码输出是什么?

public class SwitchString {

public static void main(String[] args) {

method(null);

}

public static void method(String param) {

switch (param) {

// 肯定不是进入这里

case "sth":

Log.i(TAG,"it's sth");

break;

// 也不是进入这里

case "null":

Log.i(TAG,"it's null");

break;

// 也不是进入这里

default:

Log.i(TAG,"default");

}

}

}

    1. 循环体

【推荐】循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据 库连接,进行不必要的 try-catch 操作(这个 try-catch 是否可以移至循环体外),if else等

    1. 反逻辑

【推荐】避免采用取反逻辑运算符。

说明:取反逻辑不利于快速理解,并且取反逻辑写法一般都存在对应的正向逻辑写法。

正例:使用if(x < 628) 来表达x小于628。

反例:使用if(!(x >= 628)) 来表达x小于628。

    1. while

【强制】while中的变量不要直接写成true,至少在Android应用中不要这样写,这样可能造成内存泄漏、线程耗尽等

【推荐】使用一个标志位进行判断,当需要停止时可以停止,示例如下:

while (!isDestroy) {

    …

}

  1. Android应用层方面
    1. 【强制】界面更新要在主线程

其实可能有时候没有注意会把界面更新的操作放到了子线程,我们可以在不确定当前是什么线程的有界面操作的地方加上代码看下当前是否在主线程,如果不在主线程记得切换到主线程

    1. 【强制】耗时操作放在子线程

相反耗时操作需要放在子线程,比如IO、数据库、文件、网络、数据处理等

    1. Linearlayout、ReativeLayout、ConstraintLayout

【推荐】

如果是只用一层完成的布局则应该采用顺序Linearlayout-> ReativeLayout-> ConstraintLayout

如果是复杂布局想将多层嵌套减少则应该采用顺序ConstraintLayout -> ReativeLayout-> Linearlayout

  1. Kotlin

【强制】kotlin中不要使用!!,推荐使用?.的方式,这样可以隔绝绝大部分NPE

  1. 插件

如果想在AndroidStudio中直接看到代码中的提示可以下载如下插件

然后随便点进去一个类就会有提示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1518302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

香港优才计划子女读书内地高考政策解读,3个黄金年龄段不要错过!

香港优才计划子女读书内地高考政策解读&#xff0c;3个黄金年龄段不要错过&#xff01; 孩子年龄多大&#xff0c;适合办理香港身份&#xff1f; 关注子女教育的家长们&#xff0c;应该对于“孩子有了香港身份&#xff0c;400分轻松上名校”的说法都有耳闻&#xff0c;但很少有…

altgraph的安装和用途说明

前言 altgraph 是 graphlib 的一个分支&#xff1a;一个图&#xff08;网络&#xff09;包&#xff0c;用于构建图、BFS 和 DFS 遍历、拓扑排序、最短路径等&#xff0c;带有 graphviz 输出。 安装 pip install altgraph 函数和用例 生物链 from altgraph import Graph# 定…

Python爬虫实战入门:豆瓣电影Top250(保你会,不会来打我)

文章目录 需求所需第三方库requests模块lxml模块了解 lxml模块和xpath语法xpath语法-基础节点选择语法 实战教程完整代码 需求 目标网站: https://movie.douban.com/top250 需求: 爬取电影中文名、英文名、电影详情页链接、导演、主演、上映年份、国籍、类型、评分、评分人数, …

伪装目标检测论文BGNet:Boundary-Guided Camouflaged Object Detection

论文地址:link 代码地址&#xff1a;link 这篇论文是22年的CVPR收录的一篇关于伪装目标检测的文章&#xff0c;作者主要是用了一些通道注意力和Atrous卷积来实现边缘引导的伪装目标检测&#xff0c;模型并不复杂&#xff0c;看了两天的论文和代码&#xff0c;为了加深印象在这里…

【鸿蒙 HarmonyOS 4.0】通知

一、介绍 通知旨在让用户以合适的方式及时获得有用的新消息&#xff0c;帮助用户高效地处理任务。应用可以通过通知接口发送通知消息&#xff0c;用户可以通过通知栏查看通知内容&#xff0c;也可以点击通知来打开应用&#xff0c;通知主要有以下使用场景&#xff1a; 显示接…

vscode 导入前端项目

vscode 导入前端项目 导入安装依赖 运行 参考vscode 下载 导入 安装依赖 运行 在前端项目的终端中输入npm run serve

洛谷 P5018 对称二叉树

题目背景 NOIP2018 普及组 T4 题目描述 一棵有点权的有根树如果满足以下条件&#xff0c;则被轩轩称为对称二叉树&#xff1a; 二叉树&#xff1b;将这棵树所有节点的左右子树交换&#xff0c;新树和原树对应位置的结构相同且点权相等。 下图中节点内的数字为权值&#xf…

ES6(一):let和const、模板字符串、函数默认值、剩余参数、扩展运算符、箭头函数

一、let和const声明变量 1.let没有变量提升&#xff0c;把let放下面打印不出来&#xff0c;放上面可以 <script>console.log(a);let a1;</script> 2.let是一个块级作用域,花括号里面声明的变量外面找不到 <script>console.log(b);if(true){let b1;}//und…

Ubuntu系统的安装及基础操作

目录 一、VMware虚拟机安装Ubuntu20.04过程 1、安装前的准备工作 2、VMware虚拟机创建Ubuntu操作系统 步骤一&#xff1a;以管理员的身份运行VMware虚拟机 步骤二&#xff1a;新建虚拟机 步骤三&#xff1a;选择类型配置 步骤四&#xff1a;选择安装客户机操作系统 步骤…

一文解答:wifi贴码推广什么时候开始的?

随着互联网的快速发展和智能手机的普及&#xff0c;人们的生活方式也在发生着翻天覆地的变化&#xff0c;对于网络连接的需求也变得越来越迫切。在这样的背景下&#xff0c;WiFi贴码推广作为一种便捷的网络连接方式逐渐流行起来。那么&#xff0c;WiFi贴码推广究竟是什么时候开…

PostgreSQL - 查看表膨胀空间

目录 使用pgstattuple插件查看表膨胀空间 死元组&膨胀系数清理 查看表占用磁盘空间大小是如何组成的 什么是fms和vm&#xff1f; 什么是TOAST&#xff1f; 查看表和其关联的TOAST表的oid的关系 方法一 方法二 参考文档 使用pgstattuple插件查看表膨胀空间 select…

Clickhouse 单机部署安装

前言 在大数据的时代背景下&#xff0c;数据的处理和分析能力成为企业竞争力的关键。ClickHouse&#xff0c;作为一款由俄国Yandex公司开发的分布式数据分析型数据库&#xff0c;凭借其卓越的性能和稳定性&#xff0c;赢得了业界的广泛关注。本文将介绍ClickHouse的基本概念、…

中科数安|公司办公终端、电脑文件数据 \ 资料防泄密系统

#中科数安# 中科数安是一家专注于信息安全技术与产品研发的高新技术企业&#xff0c;其提供的公司办公终端、电脑文件数据及资料防泄密系统&#xff08;也称为终端数据防泄漏系统或简称DLP系统&#xff09;主要服务于企业对内部敏感信息的安全管理需求。 www.weaem.com 该系统…

在webapp中手动发布一个应用

部署应用前&#xff0c;我们需要下载Tomcat。 下载官网: Apache Tomcat - Welcome! 1、下载 第一步 : 找到Download目录下的Tomcat8 第二步:选择下载第一个zip链接 2、下载完成后&#xff0c;解压并打开Tomcat文件 3、找到并点击webapp文件 创建一个文件夹 在创建的文件中…

蓝桥杯第十一届电子类单片机组程序设计

目录 前言 单片机资源数据包_2023&#xff08;点击下载&#xff09; 一、第十一届比赛原题 1.比赛题目 2.赛题解读 1&#xff09;计数功能 2&#xff09;连续按下无效按键 二、部分功能实现 1.计数功能的实现 2.连续按下无效按键的处理 3.其他处理 1&#xff09;对于…

【危化品泄漏源定位】基于改进哈里斯鹰优化算法的危化品泄漏源定位算法 溯源定位算法【Matlab代码#63】

文章目录 【获取资源请见文章第7节&#xff1a;资源获取】1. 算法概述2. 原始哈里斯鹰算法&#xff08;HHO&#xff09;3. 改进哈里斯鹰算法&#xff08;IHHO&#xff09;3.1 动态自适应逃逸能量3.2 动态扰动策略 4. 构建源强和位置反算模型5. 部分代码展示6. 仿真结果展示7. 资…

BigDecimal类 --java学习笔记

BigDecimal 用于解决浮点型运算时&#xff0c;出现结果失真的问题 BigDecimal常用构造器和方法&#xff1a; HALF_UP 四舍五入

Qt-QPainter drawText方法不同重载之间的区别

QPainter类的drawText方法有如下重载&#xff1a; void drawText(const QPointF &position, const QString &text) void drawText(const QPoint &position, const QString &text) void drawText(int x, int y, const QString &text) void drawText(co…

人人站CMS后台登不进去解决方案(已解决)

公司有一个网站使用的是人人站CMS&#xff0c;最近发现后台登录不进去&#xff0c;有以下报错 发生以下错误: file get contents(http://www.rrzcms.com/Public/cms/config/config.ison): failed to open stream: HTTP reguest failed! 请求的URL导致内部服务器错误。 如果您反…

三维铁木辛柯梁Matlab有限元编程 | 弹簧支座 | 弹性支撑单元| Matlab源码 | 理论文本

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…