电子开发网

电子开发网电子设计 | 电子开发网Rss 2.0 会员中心 会员注册
搜索: 您现在的位置: 电子开发网 >> 编程学习 >> Java >> 正文

JAVA开发规范

作者:佚名    文章来源:本站原创    点击数:    更新时间:2023/10/1

一、编程规范

(一)命名规范:(命名要望文知意,不要嫌长)

  1. 包名要统一小写

  1. 类名、接口名遵从驼峰式命名,DO / BO /DTO / VO / AO/PO例外

例子:MarcoPolo / UserDO / XmlService / TcpUdpDeal

  1. 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格

例子:localValue / getHttpMessage() / inputUserId

  1. 常量命名全部大写,单词间下划线隔开

例子:MAX_STOCK_COUNT

  1. 枚举类名要以Enum为后缀,且枚举成员名称要全大写,和常量命名一样

例子:枚举类名 ProcessStatusEnum 枚举成员名称 SUCCESS/UNKOWN_REASON

  1. Service/DAO层方法命名:

  1. 获取单个对象的方法用get做前缀

  1. 获取多个对象的方法用list做前缀

  1. 获取统计值的方法用count做前缀

  1. 插入的方法用save/insert做前缀

  1. 删除的方法用remove/delete做前缀

  1. 修改的方法用update做前缀

  1. 领域模型命名

  1. 查询数据库对象:xxxPO

  1. 业务逻辑层对象:xxxBO

  1. 接收客户端参数的对像:xxxVO

  1. 层级之间的数据传输对象:xxxDTO

(二)常量定义

  1. 不允许任何魔法值(即未经定义的常量)直接出现在代码中。常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量

  1. 跨应用共享常量:放置在二方库中,通常是client.jar中的constant目录下

  1. 应用内共享常量:放置在一方库中,通常是modules中的constant目录下

  1. 子工程内部共享常量:即在当前子工程的constant目录下

  1. 包内共享常量:即在当前包下单独的constant目录下

  1. 类内共享常量:直接在类内部private static final定义

  1. 如果变量值在一个范围内变化,且带有名称之外的延展属性,定义为枚举类

例子:数字就是延伸信息,标识星期几

public Enum { MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6),SUNDAY(7);}

(三)代码格式

  1. 方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之间插入一个空行。

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

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

  1. 运算符与下文一起换行。

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

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

  1. 在括号前不要换行

  1. 适当加空格进行格式整理(idea使用用快捷键ctrl+alt+L快速整理)

(四)OOP规范

  1. 所有覆写的方法,必须加@Override注解。可以准确判断是否覆盖成功。另外,如果在抽象中对方法签名进行修改,其实现类会马上编译报错

  1. 外部正在调用或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方产生影响。接口过时必须加@Deprecated 注解,并清晰地说明采用的新接口或者新服务是什么。

  1. 调用equals方法比较时,应使用常量或确定有值的对象来调用equals方法,并且包装类对象之间的比较,全部使用 equals 方法比较

  1. 关于基本数据类型和包装数据类型的使用标准:

  1. 所有的POJO类属性必须使用包装数据类型

  1. RPC方法的返回值和参数必须使用包装数据类型

  1. 所有的局部变量推荐使用基本数据类型

  1. 构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中

  1. 类内方法定义顺序依次是:公有方法或保护方法 > 私有方法 > getter/setter方法。

说明:公有方法是类的调用者和维护者最关心的方法,首屏展示最好;保护方法虽然只是子类关心,也可能是“模板设计模式”下的核心方法;而私有方法外部一般不需要特别关心,是一个黑盒实现;因为承载的信息价值较低,所有 Service 和 DAO 的 getter/setter 方法放在类体

  1. 循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。

说明:反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费

  1. 类成员与方法访问控制从严:

  1. 如果不允许外部直接通过 new 来创建对象,那么构造方法必须是 private。

  1. 工具类不允许有 public 或 default 构造方法。

  1. 类非 static 成员变量并且与子类共享,必须是 protected。

  1. 类非 static 成员变量并且仅在本类使用,必须是 private。

  1. 类 static 成员变量如果仅在本类使用,必须是 private。

  1. 若是 static 成员变量,必须考虑是否为 final。

  1. 类成员方法只供类内部调用,必须是 private。

  1. 类成员方法只对继承类公开,那么限制为 protected。

说明:任何类、方法、参数、变量,严控访问范围。过于宽泛的访问范围,不利于模块解耦

(五)集合处理

  1. 在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、删除均会产生 ConcurrentModificationException 异常。并且不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。

//正例:
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
    String item = iterator.next();
    if (删除元素的条件) {
        iterator.remove();
    }
}
//反例:
List list = new ArrayList();
list.add("1");
list.add("2");
for (String item : list) {
    if ("1".equals(item)) {
        list.remove(item);
    }
}
  1. 使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一样的数组,大小就是 list.size()。

说明:使用 toArray 带参方法,入参分配的数组空间不够大时,toArray 方法内部将重新分配

内存空间,并返回新数组地址;如果数组元素大于实际所需,下标为[ list.size() ]的数组

元素将被置为 null,其它数组元素保持原值,因此最好将方法入参数组大小定义与集合元素

个数一致。

  1. 使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。

  1. 泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用 add 方法,而<? super T>不能使用 get 方法,做为接口调用赋值时易出错。

说明:扩展说一下 PECS(Producer Extends Consumer Super)原则:第一、频繁往外读取内容的,适合用<? extends T>。第二、经常往里插入的,适合用<? super T>。

/**
* ? extends T 表示T或T的子类
* ? super T   表示T或T的父类
* ?  表示可以是任意类型
**/
class Gent<T> {
    public void test(){
        System.out.println("gent");
    }
}
class SupC {
    public void test(){
        System.out.println("supC");
    }
}
class Bc extends SupC {
    //入参只能是SupC或SupC的子类
    public void testExtends(gent<? extends SupC> o){
        System.out.println("Bc");
    }
    //入参只能是Bc或Bc的父类
    public void testSuper(gent<? super Bc> o){
        System.out.println("Bc");
    }
    //入参可以是任意类型
    public void testSuper(gent<?> o){
        System.out.println("gent");
    }
}
  1. 合理利用好集合的有序性(sort)和稳定性(order),避免集合的无序性(unsort)和不稳定性(unorder)带来的负面影响。

说明:有序性是指遍历的结果是按某种比较规则依次排列的。稳定性指集合每次遍历的元素次序是一定的。如:ArrayList 是 order/unsort;HashMap 是 unorder/unsort;TreeSet 是order/sort。

  1. 利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的contains 方法进行遍历、对比、去重操作

     //两个Set比较找出交集、差集、并集
     public static void  setCompare() {
         Set<Integer> result = new HashSet<Integer>();
         Set<Integer> set1 = new HashSet<Integer>() {{
             add(1);
             add(3);
             add(4);
         }};
         System.out.println("set1 = " + set1.toString());
         
         Set<Integer> set2 = new HashSet<Integer>() {{
             add(1);
             add(2);
             add(3);
         }};
         System.out.println("set2 = " + set2.toString());
         //交集:set1和set2相同的元素
         result.clear();
         result.addAll(set1);
         result.retainAll(set2);
         System.out.println("交集:" + result);
         //result结果:[1, 3]
         //差集:元素存在set1,但不存在set2
         result.clear();
         result.addAll(set1);
         result.removeAll(set2);
         System.out.println("差集:" + result);
         //result结果:[4]
         
         //并集:set1的set2的元素之和
         result.clear();
         result.addAll(set1);
         result.addAll(set2);
         System.out.println("并集:" + result);
         //result结果:[1, 2, 3, 4]
     }

(六)并发处理

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

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

  1. 并发修改同一记录时,避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存加锁,要么在数据库层使用乐观锁,使用 version 作为更新依据。

说明:如果每次访问冲突概率小于 20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于 3 次。

  1. 避免 Random 实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降。

说明:Random 实例包括 java.util.Random 的实例或者 Math.random()的方式。正例:在 JDK7 之后,可 以直接使用 API ThreadLocalRandom,而在 JDK7 之前,需要编码保证每个线程持有一个实例。

  1. HashMap 在容量不够进行 resize 时由于高并发可能出现死链,导致 CPU 飙升,在开发过程中可以使用其它数据结构或加锁来规避此风险

(七)控制语句

  1. 在一个 switch 块内,每个 case 要么通过 break/return 等来终止,要么注释说明程序将继续执行到哪一个 case 为止;在一个 switch 块内,都必须包含一个 default 语句并且放在最后,即使它什么代码也没有。

  1. 在 if/else/for/while/do 语句中必须使用大括号。即使只有一行代码,避免采用单行的编码方式:if (condition) statements;

  1. 表达异常的分支时,少用 if-else 方式,这种方式可以改写成:if (condition) {...return obj;}// 接着写 else 的业务逻辑代码;

说明:如果非得使用 if()...else if()...else...方式表达逻辑,避免后续代码维护困难,请勿超过 3 层。

正例:超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现,

卫语句:

//改造前(看着乱,不清楚每个逻辑分支的具体条件)
//当 a等于1
if (a == 1){
    //当 b等于2
    if (b == 2){
        ...
    } else {
        //当 b不等于1
        //c等于3
        if (c == 3){
            ...
        }
    }
}else{
    //当 a不等于1
    //当 d等于4
    if(d == 4){
        ...
    }
}
//改造后(从上到下,看着清晰明了,并清楚每个逻辑分支对应的条件)
//情况一:当 a等于1 并 b等于2
if(a == 1&&b == 2){
    ...
}
//情况二:当 a等于1 并 b不等于2 并 c等于3
if(a == 1&&b != 2&&c == 3){
    ...
}
//情况三:当 a不等于1 并 d等于4
if(a != 1&&d == 4){
    ...
}

策略模式:

/**
 * 实现不同动物发出不同声音
 * 如:狗--汪汪 猫--喵喵  牛--哞哞  羊--咩咩
 * @author gz
 * */
//改造前 (后期加多种动物类型,每次都需要修改共用的逻辑,易出错,且不易维护)
public class AnimalCryTest {
    private static final String DOG = "狗";
    private static final String CAR = "猫";
    private static final String CATTLE = "牛";
    private static final String SHEEP = "羊";
    /**
     * 动物的叫声
     * @param animalName 动物名称
     */
    public static void animalCry(String animalName){
        if (DOG.equals(animalName)){
            System.out.println(animalName+"----汪汪");
        }else if (CAR.equals(animalName)){
            System.out.println(animalName+"----喵喵");
        }else if (CATTLE.equals(animalName)){
            System.out.println(animalName+"----哞哞");
        }else {
            System.out.println(animalName+"----咩咩");
        }
    }
    
    public static void main(String[] args) {
        // 狗--汪汪
        animalCry(DOG);
        // 猫--喵喵
        animalCry(CAR);
        // 牛--哞哞
        animalCry(CATTLE);
        // 羊--咩咩
        animalCry(SHEEP);
    }
}
//改造后(后期加多种动物类型,只需要实现对应功能的接口,各个逻辑是相互独立的,不易出错,易维护)
/**
* 1、定义一个接口
**/
interface Animal {
    /**
     * 动物叫声
     */
    void animalCry();
}
/**
* 2、创建实现该接口的实现类
**/
class Dog implements Animal {
    @Override
    public void animalCry() {
        System.out.println("狗----汪汪");
    }
}
class Car implements Animal {
    @Override
    public void animalCry() {
        System.out.println("猫----喵喵");
    }
}
class Cattle implements Animal {
    @Override
    public void animalCry() {
        System.out.println("牛----哞哞");
    }
}
class Sheep implements Animal {
    @Override
    public void animalCry() {
        System.out.println("羊----咩咩");
    }
}
/**
* 3、多态性质,根据实例化对象的不同,调用实例化对象对应的具体方法
**/
public class AnimalCryTest {
    public static void main(String[] args) {
        // 创建狗的实例对象,并调用其对应的animalCry方法  狗--汪汪
        Animal dog = new Dog();
        dog.animalCry();
        // 创建猫的实例对象,并调用其对应的animalCry方法  猫--喵喵
        Animal car = new Car();
        car.animalCry();
        // 创建牛的实例对象,并调用其对应的animalCry方法  牛--哞哞
        Animal cattle = new Cattle();
        cattle.animalCry();
        // 创建羊的实例对象,并调用其对应的animalCry方法  羊--咩咩
        Animal sheep = new Sheep();
        sheep.animalCry();
    }
}

状态模式:

/**
 * 在"投了25分钱"的状态下"转动曲柄",会售出糖果;而在"没有25分钱"的状态下"转动曲柄"会提示请先投币。
 * 四个状态:
 * 1、没有硬币状态
 * 2、投币状态
 * 3、出售糖果状态
 * 4、糖果售尽状态
 * 四个动作:
 * 1、投币
 * 2、退币
 * 3、转动出糖曲轴
 * 4、发糖
 * @author gz
 */
//改造前
public class NoPatternGumballMachine{
    /*
     * 四个状态
     */
    /**没有硬币状态*/
    private final static int NO_QUARTER = 0;
    /**投币状态*/
    private final static int HAS_QUARTER = 1;
    /**出售糖果状态*/
    private final static int SOLD = 2;
    /**糖果售尽状态*/
    private final static int SOLD_OUT = 3;
    private int state = SOLD_OUT;
    private int candyCount = 0;
    public NoPatternGumballMachine(int count) {
        this.candyCount = count;
        if(candyCount > 0)
            state = NO_QUARTER;
    }
    /*
     * 四个动作
     */
    /**
     * 投币
     */
    public void insertQuarter() {
        if(NO_QUARTER == state){
            System.out.println("投币");
            state = HAS_QUARTER;
        }
        else if(HAS_QUARTER == state){
            System.out.println("请不要重复投币!");
            returnQuarter();
        }
        else if(SOLD == state){
            System.out.println("已投币,请等待糖果");
            returnQuarter();
        }else if(SOLD_OUT == state){
            System.out.println("糖果已经售尽");
            returnQuarter();
        }
    }
    /**
     * 退币
     */
    public void ejectQuarter() {
        if(NO_QUARTER == state){
            System.out.println("没有硬币,无法弹出");
        }
        else if(HAS_QUARTER == state){
            returnQuarter();
            state = NO_QUARTER;
        }
        else if(SOLD == state){
            System.out.println("无法退币,正在发放糖果,请等待");
        }else if(SOLD_OUT == state){
            System.out.println("没有投币,无法退币");
        }
    }
    /**
     * 转动出糖曲轴
     */
    public void turnCrank() {
        if(NO_QUARTER == state){
            System.out.println("请先投币");
        }
        else if(HAS_QUARTER == state){
            System.out.println("转动曲轴,准备发糖");
            state = SOLD;
        }
        else if(SOLD == state){
            System.out.println("已按过曲轴,请等待");
        }else if(SOLD_OUT == state){
            System.out.println("糖果已经售尽");
        }
    }
    /**
     * 发糖
     */
    public void dispense() {
        if(NO_QUARTER == state){
            System.out.println("没有投币,无法发放糖果");
        }
        else if(HAS_QUARTER == state){
            System.out.println("this method don't support");
        }
        else if(SOLD == state){
            if(candyCount > 0){
                System.out.println("分发一颗糖果");
                candyCount --;
                state = NO_QUARTER;
            }
            else{
                System.out.println("抱歉,糖果已售尽");
                state = SOLD_OUT;
            }
        }else if(SOLD_OUT == state){
            System.out.println("抱歉,糖果已售尽");
        }
    }
    /**
     * 退还硬币
     */
    protected void returnQuarter() {
        System.out.println("退币……");
    }
}
//改造后
//1、定义一个接口或者抽象类,抽象出几个行为状态
public abstract class State {
    /**
     * 投币
     */
    public abstract void insertQuarter();
    /**
     * 退币
     */
    public abstract void ejectQuarter();
    /**
     * 转动出糖曲轴
     */
    public abstract void turnCrank();
    /**
     * 发糖
     */
    public abstract void dispense();
    /**
     * 退还硬币
     */
    protected void returnQuarter() {
        System.out.println("退币……");
    }
}
// 2、为每个状态实现接口或基类
/**
 * 没有硬币的状态
 */
public class NoQuarterState extends State{
    GumballMachine gumballMachine;
    public NoQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }
    @Override
    public void insertQuarter() {
        System.out.println("你投入了一个硬币");
        //转换为有硬币状态
        gumballMachine.setState(gumballMachine.hasQuarterState);
    }
    @Override
    public void ejectQuarter() {
        System.out.println("没有硬币,无法弹出");
    }
    @Override
    public void turnCrank() {
        System.out.println("请先投币");
    }
    @Override
    public void dispense() {
        System.out.println("没有投币,无法发放糖果");
    }
}
/**
 * 投硬币的状态
 */
public class HasQuarterState extends State{
    GumballMachine gumballMachine;
    public HasQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }
    @Override
    public void insertQuarter() {
        System.out.println("请不要重复投币!");
        returnQuarter();
    }
    @Override
    public void ejectQuarter() {
        returnQuarter();
        gumballMachine.setState(gumballMachine.noQuarterState);
    }
    @Override
    public void turnCrank() {
        System.out.println("转动曲轴,准备发糖");
        gumballMachine.setState(gumballMachine.soldState);
    }
    @Override
    public void dispense() {
        System.out.println("this method don't support");
    }
}
/**
 * 出售的状态
 */
public class SoldState extends State{
    GumballMachine gumballMachine;
    public SoldState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }
    @Override
    public void insertQuarter() {
        System.out.println("已投币,请等待糖果");
        returnQuarter();
    }
    @Override
    public void ejectQuarter() {
        System.out.println("无法退币,正在发放糖果,请等待");
    }
    @Override
    public void turnCrank() {
        System.out.println("已按过曲轴,请等待");
    }
    @Override
    public void dispense() {
        int candyCount = gumballMachine.getCandyCount();
        if(candyCount > 0){
            System.out.println("分发一颗糖果");
            candyCount--;
            gumballMachine.setCandyCount(candyCount);
            if(candyCount > 0){
                gumballMachine.setState(gumballMachine.noQuarterState);
                return;
            }
        }
        System.out.println("抱歉,糖果已售尽");
        gumballMachine.setState(gumballMachine.soldOutState);
    }
}
/**
 * 售尽的状态
 */
public class SoldOutState extends State{
    GumballMachine gumballMachine;
    public SoldOutState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }
    @Override
    public void insertQuarter() {
        System.out.println("糖果已经售尽");
        returnQuarter();
    }
    @Override
    public void ejectQuarter() {
        System.out.println("没有投币,无法退币");
    }
    @Override
    public void turnCrank() {
        System.out.println("糖果已经售尽");
    }
    @Override
    public void dispense() {
        System.out.println("糖果已经售尽");
    }
}
//3、将糖果机的动作委托到状态类
public class GumballMachine extends State{
    public State noQuarterState = new NoQuarterState(this);
    public State hasQuarterState = new HasQuarterState(this);
    public State soldState = new SoldState(this);
    public State soldOutState = new SoldOutState(this);
    private State state = soldOutState;
    private int candyCount = 0;
    public GumballMachine(int count) {
        this.candyCount = count;
        if(count > 0)
            setState(noQuarterState);
    }
    @Override
    public void insertQuarter() {
        state.insertQuarter();
    }
    @Override
    public void ejectQuarter() {
        state.ejectQuarter();
    }
    @Override
    public void turnCrank() {
        state.turnCrank();
    }
    @Override
    public void dispense() {
        state.dispense();
    }
    public void setState(State state) {
        this.state = state;
    }
    public State getState() {
        return state;
    }
    public void setCandyCount(int candyCount) {
        this.candyCount = candyCount;
    }
    public int getCandyCount() {
        return candyCount;
    }
}

从代码里面可以看出,糖果机根据此刻不同的状态,而使对应的动作呈现不同的结果。这份代码已经可以满足我们的基本需求,但稍微思考一下,你会觉得这种实现代码似乎,功能太复杂了,扩展性很差,没有面向对象的风格。

假设由于新需求,要增加一种状态,那每个动作方法我们都需要修改,都要重新增加一条else语句。而如果需求变更,某个状态下的动作需要修改,我们也要同时改动四个方法。这样的工作将是繁琐而头大的。

可以发现,这种模式下,糖果机根本不需要清楚状态的改变,它只用调用状态的方法就行。状态的改变是在状态内部发生的。这就是"状态模式"。

如果此时再增加一种状态,糖果机不需要做任何改变,我们只需要再增加一个状态类,然后在相关的状态类方法里面增加转换的过程即可

  1. 除常用方法(如 getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。

说明:很多 if 语句内的逻辑相当复杂,阅读者需要分析条件表达式的最终结果,才能明确什么样的条件执行什么样的语句,那么,如果阅读者分析逻辑表达式错误呢?

正例:
// 伪代码如下
final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed) {
...
}
反例:
if ((file.open(fileName, "w") != null) && (...) || (...)) {
...
}

(八)注释规范

  1. 类、类属性、类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用// xxx 方式

  1. 所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。

  1. 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/ /注释,注意与代码对齐。

  1. 所有的枚举类型字段必须要有注释,说明每个数据项的用途。

  1. 代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。代码和注释要同步更新

  1. 对于注释的要求:第一、能够准确反应设计思想和代码逻辑;第二、能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。注释要尽可能精简准确、表达到位,要避免过多过滥的注释。

  1. 特殊注释标记,请注明标记人与标记时间。注意及时处理这些标记,通过标记扫描,经常清理此类标记。线上故障有时候就是来源于这些标记处的代码。

  1. 待办事宜(TODO):( 标记人,标记时间,[预计处理时间])表示需要实现,但目前还未实现的功能。这实际上是一个 Javadoc 的标签,目前的 Javadoc还没有实现,但已经被广泛使用。只能应用于类,接口和方法(因为它是一个 Javadoc 标签)。

  1. 错误,不能工作(FIXME):(标记人,标记时间,[预计处理时间])在注释中用 FIXME 标记某代码是错误的,而且不能工作,需要及时纠正的情况。

(九)其他

  1. 获取当前毫秒数 System.currentTimeMillis(); 而不是 new Date().getTime();说明:如果想获取更加精确的纳秒级时间值,使用 System.nanoTime()的方式。在 JDK8 中,针对统计时间等场景,推荐使用 Instant 类

  1. 不要在controller层加任何复杂的逻辑

  1. 任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存

  1. 一个方法体不要过长,要对逻辑进行拆分,尽量不要超过80行

Tags:java,编程入门,开发规范  
责任编辑:admin
请文明参与讨论,禁止漫骂攻击。 昵称:注册  登录
[ 查看全部 ] 网友评论
热门文章
  • 此栏目下没有热点文章
关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 在线帮助 - 文章列表
返回顶部
刷新页面
下到页底
晶体管查询