在SpringBoot的源码中有看到使用abstract关键字定义的工具类,如:
1 2 3 4 5 6 7 8 9 |
package org.springframework.util; public abstract class StringUtils { public static boolean isEmpty(@Nullable Object str) { return (str == null || "".equals(str)); } } |
使用abstract关键字的目的猜测应该是为了避免实例化。
同样为了避免实例化,在jdk中定义的工具类则通常是使用私有化构造器来实现的:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package java.util; public class Collections { // Suppresses default constructor, ensuring non-instantiability. private Collections() { } public static <T extends Comparable<? super T>> void sort(List<T> list) { list.sort(null); } } |
目的都是为了避免实例化,这两种方案无非是“茴”字的不同写法而已。
我自己比较偏好第二种写法,原因有二:
- abstract关键字在语义上的作用不是简单的为了避免实例化,更何况说是用来定义工具类了
- 阿里p3c的规范要求Java工具类使用第二种方案(安装了相关插件,每次都被提醒很头疼的)
但对于第二种方案我通常习惯更多做一些事情,比如下例:
1 2 3 4 5 6 7 |
public final class Strings { private Strings() { throw new UnsupportedOperationException("Private constructor, cannot be accessed."); } } |
在工具类定义时添加了final关键字避免被继承修改;在私有构造器里面抛出了异常以防止私有构造器被反射调用。当然这也有可能是我杞人忧天了。如果真的有心要做些什么,通常也是防不住的。
在StackOverflow上也有对这个问题的讨论:Should Helper/Utility Classes be abstract?。有趣的是乱入了一些C# Developer,让我们有机会一窥其他语言中的特色。
End!
赞,感谢分享