💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] ### **1. return 一个空的集合,而不是 null** 如果一个程序返回一个没有任何值的集合,请确保一个空集合返回,而不是空元素。这样你就不用去写一大堆 ”if else” 判断null元素。 ![](https://img.kancloud.cn/bb/e4/bbe4ddc3152519082b0df284f0f02e77_640x270.png) Java的标准库设计者已经在 Collections 类中放了一个空的 List 常量 EMPTY\_LIST,除此之外,还有 EMPTY\_MAP, EMPTY\_SET ### **2. 小心使用 String连接** 因为字符串相加或者拼接的方式都会在对象池中查找字符串是否存在,如果不存在则创建,这样在拼接的过程中会产生大量中间过程的字符串,占用内存资源。StringBuilder效率优于StringBuffer,但是StringBuffer线程安全。 ### 3. 避免空指针 下面说几个空指针的几个最常见的案例及解决之道。 #### 1、字符串比较,常量放前面 ~~~ if(status.equals(SUCCESS)){ } ~~~ 这个时候 status 可能为 null 造成空指针异常,应该把常量放前面,就能避免空指针异常。 ~~~ if(SUCCESS.equals(status)){ } ~~~ 这个应该在各种开发规范里面都会提到,也是最基础的。 #### 2、初始化默认值 在对象初始化的时候给它一个默认值或者默认构造实现,如: ~~~ User user = new User(); String name = StringUtils.EMPTY; ~~~ #### 3、返回空集合 在返回一个集合的话,默认会是 null,统一规范返回一个空集合。 举个 List 例子,如: ~~~ public List getUserList(){ List list = userMapper.gerUserList(); return list == null ? new ArrayList() : list; } ~~~ 这样接收方就不用担心空指针异常了,也不会影响业务。 #### 4、断言 断言是用来检查程序的安全性的,在使用之前进行检查条件,如果不符合条件就报异常,符合就继续。 Java 中自带的断言关键字:assert,如: ~~~ assert name == null : "名称不能为空"; ~~~ 输出: ~~~ Exception in thread "main" java.lang.AssertionError: 名称不正确 ~~~ 不过默认是不启动断言检查的,需要要带上 JVM 参数:-enableassertions 才能生效。 Java 中这个用的很少,建议使用 Spring 中的,更强大,更方便好用。 Spring中的用法: ~~~ Assert.notNull(name,"名称不能为空"); ~~~ #### 5、Optional Optional 是 JDK 8 新增的新特性,再也不用 != null 来判断了,这个在一个对象里面的多个子对象连续判断的时候非常有用。 ### 4. 检查null和长度 > 不管什么时候你有一个集合、数组或者其他的,确保它存在并且不为空。 > 在学习前期这样的行为对你来说可能是多此一举,但对于已经工作或者做过项目的小伙伴来说,相信这样的代码对 Java7的Objects工具类,提供类对Object的相关操作 ![](https://img.kancloud.cn/6b/ab/6bab9ea68a669e6736cb4d2e3497e214_872x400.png) ### 5. switch语句末尾总是加上default ``` int num = 4; switch (num){ case 1: System.out.println("值为1"); break; case 2: System.out.println("值为2"); break; default: System.out.println("无此值"); } ``` ### 6. 使用 String.valueOf(value) 代替 ""+value 将其他值转换成字符串时,这样String.valueOf(value)效率会更高 ``` Integer num = 1; String str = "" + num; String string = String.valueOf(num); System.out.println(str); System.out.println(string); ``` ### 7. 尽量使用基本数据类型代替对象 ``` String str = “hello”; ``` > 上面这种方式会创建一个“hello”字符串,而且JVM的字符缓存池还会缓存这个字符串 ``` String str = new String(“hello”); ``` > 此时程序除创建字符串外,str所引用的String对象底层还包含一个char数组,这个char数组依次存放了h,e,l,l,o ### 8. 不要用 NullPointerException进行空指针捕获 > 空指针异常应该用代码规避(比如检测不为空),而不是用捕获异常的方式处理 ### 9. Bean 中的链式风格 什么是链式风格?我来举个例子,看下面这个 Student 的 Bean: ~~~ public class Student { private String name; private int age; public String getName() { return name; } public Student setName(String name) { this.name = name; return this; } public int getAge() { return age; } public Student setAge(int age) { return this; } } ~~~ 仔细看一下 set 方法,这样的设置便是 chain 的 style,调用的时候,可以这样使用: ~~~ Student student = new Student() .setAge(24) .setName("zs"); ~~~ 相信合理使用这样的链式代码,会更多的程序带来很好的可读性,那看一下**如果使用 Lombok 进行改善呢,请使用 @Accessors(chain = true),看如下代码:** ~~~ @Accessors(chain = true) @Setter @Getter public class Student { private String name; private int age; } ~~~ 这样就完成了一个对于 Bean 来讲很友好的链式操作。 ### 10. Lombok静态构造方法 使用lombok(@RequiredArgsConstructor 和 @NonNull): ~~~ @Accessors(chain = true) @Setter @Getter @RequiredArgsConstructor(staticName = "ofName") public class Student { @NonNull private String name; private int age; } ~~~ 测试代码: ~~~text Student student = Student.ofName("zs"); ~~~ 这样构建出的 bean 语义是否要比直接 new 一个含参的构造方法(包含 name 的构造方法)要好很多。当然,看过很多源码以后,我想相信将静态构造方法 ofName 换成 of 会先的更加简洁: ~~~ @Accessors(chain = true) @Setter @Getter @RequiredArgsConstructor(staticName = "of") public class Student { @NonNull private String name; private int age; } ~~~ 测试代码: ~~~ Student student = Student.of("zs"); ~~~ 当然它仍然是支持链式调用的: ~~~ Student student = Student.of("zs").setAge(24); ~~~ 这样来写代码,真的很简洁,并且可读性很强。 ### 11. 使用 Builder Builder 模式我不想再多解释了,读者可以看一下 Head First(《设计模式》)的建造者模式。 今天其实要说的是一种变种的 Builder 模式,那就是构建 Bean 的 Builder 模式,其实主要的思想是带着大家一起看一下 Lombok 给我们带来了什么。 看一下 Student 这个类的原始 Builder 状态: ~~~ public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static Builder builder(){ return new Builder(); } public static class Builder{ private String name; private int age; public Builder name(String name){ this.name = name; return this; } public Builder age(int age){ this.age = age; return this; } public Student build(){ Student student = new Student(); student.setAge(age); student.setName(name); return student; } } } ~~~ 调用方式: ~~~ Student student = Student.builder().name("zs").age(24).build(); ~~~ 这样的 Builder 代码,让我是在恶心难受,于是我打算用 Lombok 重构这段代码: ~~~ @Builder public class Student { private String name; private int age; } ~~~ 调用方式: ~~~ Student student = Student.builder().name("zs").age(24).build(); ~~~ ### 13. 复杂代码拆分,减少代码层级