1. 类设计原则
solid 类设计原则:
单一职责原则(SRP):一个类应该只负责一件事。
开闭原则(OCP):软件组件应该对扩展开发,对修改关闭。
里氏替换原则(LSP):子类必须能够完全替换基类。
接口隔离原则(ISP):客户端不应该依赖他不需要的接口。
依赖导致原则(DIP):依赖抽象,而不是细节。
2. 静态类处理异常
public class TestExceptions {
public static void main(String[] args)
{
try
{
throw new DBExeption.NoData("No row found for id : x");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
优点:
- 即便开发者写了难以读懂的错误信息,也可以弄懂具体错误。
- 支持不同异常实例处理不同的异常场景。
- 不需要使用单个异常覆盖许多异常的情况。
- 日志更具有意义和可读性。
3. Java 异常
java中的异常层次结构
- 不要吞下异常,要做处理。
- 抛出已检查的异常
- 不要捕获 Exception 类而是捕获特定的子类
- 永远不要抓住 Throwable 类
- 始终正确地将异常包装在自定义异常中,以便不会丢失堆栈跟踪
- 记录异常或抛出它但从不同时执行
- 永远不要从 finally 块中抛出任何异常
- 始终只捕获您可以实际处理的异常
- 不要使用 printStackTrace()语句或类似方法
- 如果您不打算处理异常,请使用 finally 块而不是 catch 块
- 记住“提早赶快”的原则
- 处理异常后始终清理
- 仅从方法中抛出相关的异常
- 切勿在程序中使用流控制异常
- 验证用户输入以在请求处理的早期捕获不利条件
- 使用模板方法重复 try-catch
4. Spring 配置文件最佳实践
1)为每个配置文件添加标题注释
2)使用一致的命名约定
3)架构引用中没有版本号
4)优先选择构造函数注入的 setter 注入
5)首选构造函数参数匹配的索引类型
6)在扩展表单上使用快捷方式表单
7)尽可能重用 bean 定义
8)始终使用 id 作为 bean 标识符
9)尽量避免自动装配
10)始终使用类路径前缀
11)始终外部化属性
12)在开发阶段使用依赖性检查
13)不要滥用/过度使用依赖注入
5. Java 包装类内部缓存
整数缓存
public class IntegerCacheDemo {
public static void main(String[] args) {
Integer a1 = 100;
Integer a2 = 100;
Integer a3 = new Integer(100);
System.out.println(a1 == a2);
System.out.println(a1 == a3);
}
}
Output:
true
false
第一个print语句将打印为true; 表示两个变量都指向同一个实例。但是,第二个print语句打印为false,因为新的Integer(..)在单独的内存位置创建了一个新的实例。因此,如果要使用此缓存,请始终使用原始赋值来引用变量或使用valueOf()方法。
修改缓存大小
如果要存储更多实例,可以使用运行时参数,如下所示:
-Djava.lang.Integer.IntegerCache.high = 2000
上面的语句将使缓存存储从-127到1000的实例。请记住,截至目前,没有像-Djava.lang.Integer.IntegerCache.low这样的属性。可能在将来,也可能会添加。
其他包装类
在上面的讨论中,我已经讨论过Integer类中的缓存,但是如果事实上所有的包装类都提供了这种功能。以免见到它们:
- java.lang.Boolean将两个内置实例存储为TRUE和FALSE,如果未使用new关键字,则返回它们的引用。
- java.lang.Character有一个缓存,用于unicodes 0和127之间的字符(ascii-7 / us-ascii)。
- java.lang.Long的缓存长度介于-128到+127之间。
- java.lang.String有一个全新的字符串池概念。
6. ToString 最佳实践
- Java 使用 ToStringBuilder 覆盖 toString()
7. Java 8 Streams
另一个重大变化是Java 8 Streams API,它提供了一种以各种方式处理一组数据的机制,包括过滤,转换或任何其他可能对应用程序有用的方式。
Java 8中的Streams API支持不同类型的迭代,您只需定义要处理的项集,要对每个项执行的操作以及要存储这些操作的输出。
流API的示例。在此示例中,items 是 String 值的集合,您希望删除以某些前缀文本开头的条目。
List items;
String prefix;
List filteredList = items.stream().filter(e -> (!e.startsWith(prefix))).collect(Collectors.toList());
这 items.stream()
表示我们希望 items
使用Streams API处理集合中的数据。
8. Java 8日期/时间API更改
新的日期和时间API /类(JSR-310),也称为ThreeTen,它们只是改变了您在Java应用程序中处理日期的方式。
日期
Date
阶级甚至已经过时了。用于替换Date类的新类是LocalDate
,LocalTime
和LocalDateTime
。
- 本
LocalDate
类代表一个日期。没有时间或时区的表示。 - 这个
LocalTime
班代表一个时间。没有日期或时区的表示。 - 本
LocalDateTime
类代表一个日期-时间。没有时区的表示。
如果您希望使用区域信息的日期功能,那么拉姆达为您提供额外的3类类似于一个,即上面OffsetDate
,OffsetTime
和OffsetDateTime
。时区偏移可以用“+05:30”或“欧洲/巴黎”格式表示。这是通过使用另一个类来完成的ZoneId
。
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.of(12, 20);
LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
时间戳和持续时间
为了在任何时刻表示特定的时间戳,需要使用的是类Instant
。本Instant
类表示时间纳秒的精度瞬间。Instant上的操作包括与另一个操作的比较Instant
以及添加或减去持续时间。
Instant instant = Instant.now();
Instant instant1 = instant.plus(Duration.ofMillis(5000));
Instant instant2 = instant.minus(Duration.ofMillis(5000));
Instant instant3 = instant.minusSeconds(10);
Duration
class是java语言中第一次带来的全新概念。它表示两个时间戳之间的时差。
Duration duration = Duration.ofMillis(5000);
duration = Duration.ofSeconds(60);
duration = Duration.ofMinutes(10);
Duration
处理小的时间单位,如毫秒,秒,分钟和小时。它们更适合与应用程序代码交互。要与人交互,你需要获得更大的持续时间,这些持续时间与Period
课程一起呈现。
Period period = Period.ofDays(6);
period = Period.ofMonths(6);
period = Period.between(LocalDate.now(), LocalDate.now().plusDays(60));