命名规范
命名规范:
- 不能以下划线或美元符号开始,也不能以下划线或美元符号结束
- 反例: _name / __name / O b j e c t / n a m e _ / n a m e Object / name\_ / name Object/name_/name / Object$
类名规范:
- 类名使用 UpperCamelCase 风格,必须遵从驼峰形式。
- 但以下情形例外: (领域模型的相关命名 )DO / BO / AO / PO / DTO / VO / DAO等。
①正例: MarcoPolo / UserVO /
②反例: macroPolo / UserVo/ - Service /DAO接口类名必须以字母 I 开头,实现类必须 Impl 结尾
①正例: IUserDAO / UserDAOImpl /
②反例: UserDAO / UserDAO / - 根据类命名时体现它用途、设计模式。(推荐)
方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从驼峰形式:
- 正例: localValue / getHttpMessage() / inputUserId
- 反例: localvalue / gethttpmessage() / inputuserid
- 禁止使用xxPO作为临时变量。
常量命名全部大写,单词间用下划线隔开:
- 正例: MAX_STOCK_COUNT
- 反例: max_stock_count
- DAO中sql的常量必须为:SQL +下划线+对应方法名的大写下划线分割单词的形式 例如:private static final String SQL_FIND_USER_INFO=“”;
包名package都统一使用小写:
- 正例:package cn.com.do1.compoment.form.queryreport
- 反例:package cn.com.do1.compoment.form.queryReport
- java包各模块命名规则:
①action,ui,controller为控制层:有时也会命名为“controller”即MVC中充当C角色,用来分配哪个业务来处理用户请求。
②biz,service业务层:存放好多处理业务的代码,现实中面向接口编程,一般这里定义都是业务接口,通常会有一个biz.impl这个包用来写实现类. 当然针对架构意义实现类不用说。
③dao持久层:数据库操作都写在这里。
④util功能包:针对本项目工具类。
⑤common通用工具包:一般一个公司会有固定的jar,好几个项目通用的,例如远程调用等。
⑥domian,model,po,vo存放实体:通常一些对应数据表的实体类放在此,如果用Mybatis框架,一般mapping创建在它下面,当然只针对架构mapping也是无意义。
⑦包名除了以上的类名对应啥就起啥,例如:filter,listener等等,因为不是所有模块都用到过滤器或者监听器。
代码和注释中都要避免使用任何语言的种族歧视性词语:
- 正例:日本人 / 印度人 / blockList / allowList / secondary
- 反例:RIBENGUIZI / Asan / blackList / whiteList / slave
编码规范
调用第三方接口:
- 在使用时要设置超时时长,建议接口超时时长在1-3秒之间
权限、角色、用户:
- 页面权限简单优化,同一个实例表三个权限:
①XX功能查阅(概括列表详情,导出),
②XX功能编辑(导入、新增、编辑,修改xxx,编辑xxx、启用禁用),
③XX功能删除。 - 权限命名规范:名词+动词
前后端的null与空串与不传:
前端:
①前端不传某个字段,后端不会调用对应字段的get/set方法,后端为空。
②前端传了某个字段,但只写参数名,不写参数值,后端调用对应字段的get/set方法,后端设置为空,因此也为空。
③前端传了某个字段,写了参数名,但参数值写为空串(“”),后端调用对应字段的get/set方法,后端设置为双引号字符串(“”“”)。
④前端传了某个字段,写了参数名和对应的参数值,后端调用对应字段的get/set方法,后端设置为对应的参数值。数据库:
①后端不传某个字段,jdbc不会调用对应字段的get/set方法,数据Bean对应的参数默认就为空,mysql不处理该参数。
②后端传了某个字段,写了参数名,但参数值为空,jdbc调用对应字段的get/set方法,jdbc设置为空,因此数据Bean也为空,MySQL不处理该参数。
③后端传了某个字段,写了参数名,但参数值写为空串(“”),jdbc调用对应字段的get/set方法,jdbc设置为空串,数据Bean设置该参数为空串,mysql处理该参数为空串。
④后端传了某个字段,写了参数名和对应的参数值,jdbc调用对应字段的get/set方法,jdbc设置为对应的参数值,数据bean和mysql都设置相应的参数和参数值。- 注意:
①mysql图形化客户端中的某个字段没有显示值就是该值为null。
- 总结:
①因此空串没有啥意义,传入时应该避免空串,因此判断时需要增加判断是否空串。此外对于集合的空集合和空串是一样的,在判断时需要增加判断是否空集合。
②其实开发时按照一个规范更好,但为什么不能完全实施呢,因为不能保证公司中其他开发人员是否严格按照开发规范来开发,因此需要防止。
Dao层和Service层使用:
除了service谁都不可以直接调用DAO,因为事务处理在Service,必须经过Service。
- Action,Util都不可以调用。DAO所有方法应该逻辑很简单。
A功能的DAO,B功能的service不能直接调用,要经过A功能的service,防止业务混乱。
java三元运算符优缺点:
- 三元元素的格式:【条件控制语句】 ? 【表达式1】 : 【表达式2】。
- 优点:一些简单的逻辑判断三元运算符可以简化代码,去除多余的 if-else 语句。
- 缺点:三元运算符使用时必须有返回值,没有返回值的表达式是不可以使用的。
- 注意点:
表达式一和表达式二的值类型不一致,会强制拆箱升级成范围更大的那个表达式的类型。
- 链接:java三元运算符缺点_《java基础》我踩过三元运算符的坑
java中变量的判空场景:
- 引用类型变量(包括String)一定要判空。(看情况)
①通过方法得到的引用变量,看方法内部处理,若方法不可能返回null,则不用判空,若方法会返回null,则需要在调用方法的地方进行判空。
②若调用方法得到的引用变量后,不使用引用变量调用方法(从而不报空指针),也可以不判空。 - 总结:
①判不判空不是死的,是活的。
②根据方法内部逻辑,以及调用方法处的逻辑综合判断。
判空时,不是单单判断null,在集合或字符串时可能还需判断集合的长度和是否空串。
静态变量、枚举的使用场景:
- 枚举的实现原理就是定义一个类,然后实例化几个由final修饰的这个类的对象,每个实例都带有自己的元信息。而常量相比之下,没有这一层封装,只占用最基本的内存,包括引用,和它的值本身,要简单轻巧很多。如果值可以使用基本类型而不是包装类型,那更不用说了。
- 不过话又说回来,通常情况下我们没必要在意这种区别。如果用枚举可读性、可扩展性更好,用就是了,枚举占那点内存,沧海一粟。在性能与代码维护性之间,除个别情况,优先选后者。高级编程语言的诞生本身就是硬件提升的背景下,牺牲某些性能来降低开发门槛,提高开发效率的,相对于微小的性能损耗,人力成本更值钱。
- 链接:静态变量、枚举、以及静态代码块的使用场景
- 当在和前台传过来的数据或者在逻辑操作的代码里面需要去用到这个常量值去做比较的时候,就是使用枚举类型的时候。一般形式是: 类名.枚举类型名.单个枚举类型。
- 就是在自己的代码里面,要是想使代码很规范,不被吊打,那么写出来的逻辑代码里面是不应该出现常量字符串和常量数字之类的东西。例如代码里面出现数字:
100,8,或者其他的数字,字符串如:只要是在逻辑代码里面带引号的。
这些代码,你写出来虽然在功能上是没有问题的,但是,这些都是隐藏的炸弹。好的代码,是不会出现这个问题的。这些东西都应该被定义成一个常量,然后再在其他地方使用。此外具有具体意义的要写成常量 。 - 怎么循环一个枚举类型。枚举有一个方法,values(),使用形式如: int length = XXXX.values().length 。
- 链接:java 枚举 循环遍历以及一些简单常见的使用
- 总结:
①循环使用到的地方最好使用枚举,因为枚举类有方法可以调用。
②1,"|"等等这些符号是用静态常量。
③其他随意。
JAVA当中变量什么时候需要初始化:
- 对于类的成员变量,不管程序有没有显式的进行初始化,Java虚拟机都会先自动给它初始化为默认值。
- 局部变量声明之后,Java虚拟机就不会自动给它初始化为默认值,因此局部变量的使用必须先经过显式的初始化。
但是需要声明的是:对于只负责接收一个表达式的值的局部变量可以不初始化,参与运算和直接输出等其它情况的局部变量需要初始化。
java的static静态变量与静态方法何时使用:
对于静态变量来说,多线程会使用它,对于变量来说,如果类是单例的,多线程也会使用它。
- 就是我们平常web开发中,很少会使用主动使用多线程,但是还有一种多线程情况就是每个用户都是一个线程,当访问量很大的时候是不是也就是多线程了呢,可是这种时候你使用非静态成员变量是没问题的,因为每个用户都是不同的实例,每个用户都是new的新的类对象,所以类中的变量也都是互相不干扰的,也就是线程安全的,但如果是静态变量,就是多用户共享,也就是多线程共享,所以多个用户同时修改数据时就会出现问题,难道我们平常开发中每次使用静态变量都要考虑线程安全问题吗。
- 这是线程安全的问题,建议了解一下线程安全机制。线程安全性比较关键的两个点:内存可见性和操作原子性。
- 如果你不修改值,可以使用private static final int ,final可以保证内存可见性语义。对于原生变量,final修饰后不可更改,从而也不存在操作原子性的问题。
- 如果你只是想单纯地进行赋值,而不进行复合操作,如i++,i=i+1之类的。那么可以使用volatile int。volatile可以确保内存可见性,但是无法确保原子性,所以不支持复合操作的线程安全性。
- 如果你想进行复合操作,可以使用AtomicInteger这个原子类,支持CAS操作,可确保内存可见性和操作原子性。
- 为什么会存在线程安全性问题?
①简要说一下,java中所有的线程都共享jvm进程的虚拟内存地址空间。一般的共享变量存放在这共享区域中。但是每个线程还有自己的本地缓存,在线程读取变量时,会在其本地拷贝一份副本进行操作,这样就会导致共享内存和本地副本存在不一致的情况。
②如果想深入理解,可以看一下cpu的缓存机制. - 链接:java的static静态变量是不是不安全的?应该如何正确的使用他呢
- 在多线程中使用静态方法是否有线程安全问题?
①在多线程中使用同一个静态方法时,每个线程使用各自的实例字段(instance field)的副本,而共享一个静态字段(static field)。所以说,如果该静态方法不去操作一个静态成员,只在方法内部使用实例字段(instance field),不会引起安全性问题。但是,如果该静态方法操作了一个静态字段,则需要静态方法中采用互斥访问的方式进行安全处理。
- 何时使用静态?何时不使用静态?
①看这个方法或字段需不需要类共享。
使用MAP和实体类作为参数的优缺点:
- map的优点:
1、灵活性强于javabean,易扩展,耦合度低。
2、写起来简单,代码量少。
3、mybatis 查询的返回结果本身就是MAP,可能会比返回javabean快 - map的缺点:
1、javabean在数据输入编译期就会对一些数据类型进行校验,如果出错会直接提示。而map的数据类型则需要到sql层,才会进行处理判断。
2、map的参数名称如果写错,也是需要到sql层,才能判断出是不是字段写错,不利于调试等。相对而言javabean会在编译期间发现错误
3、map的参数值如果多传、乱传,也是需要到sql层,才能判断出是不是字段写错,不利于调试等。相对而言javabean会在编译期间发现错误
4、仅仅看方法签名,你不清楚Map中所拥有的参数个数、类型、每个参数代表的含义。 后期人员去维护,例如需要加一个参数等,如果项目层次较多,就需要把每一层的代码都了解清楚才能知道传递了哪些参数。 - Javabean的优点:
1、面向对象的良好诠释、
2、数据结构清晰,便于团队开发 & 后期维护。
3、代码足够健壮,可以排除掉编译期错误 - javabean的缺点:
1、代码量增多,大量时间去封装用到的表对象。
2、可能会影响开发效率。 - 总结:权衡利弊,如果团队开发还是javabean比较好,个人项目就无所谓了。追求高效开发,可以使用Map
状态、类型等常量规范:
- 状态类型等常量数据,使用枚举或者全局变量统一管理,并在注释中描述清楚意义,方便二次开发人员理解语义。
- 正例:contactService.getContactSyncCorpIdList(ContactSyncStatus.STATUS_WAIT)
- 反例:
TbQyExperienceAgentHistoryPO h