一些我认为有用有趣的JDK方法
/ 8 min read
在学习JDK的源码过程中我遇到了一些有趣有用的方法,在此之前如果要使用这些工具方法,我首先会想到的是commons-lang
和guava
这样的语言扩展包,但现在如果是写一些demo,使用原生即可达到目的。当然我们也不能否认它们的作用,在平时的工作项目中几乎都会引入这些语言扩展包,直接使用他们也使得编程风格统一,而且还能够对低版本的JDK提供支持。
以下收集的代码片段可能会逐渐增加,也可能不会。
java.util.Objects
java.util.Objects
工具类,我觉得好用的几个方法
除此之外还应该从Objects
学习到编写工具类的正确的规范,
- 定义为final class
- 只定义一个无参的构造函数且抛出断言错误,防止被反射调用
- 工具方法都是静态方法
- 静态方法中只抛出unchecked异常
java.lang.System
这个最早应该是在Hello World程序中见到的,推荐它的一个方法
注释写得很明白了,不管一个对象实例的class有没有覆盖Object的hashCode方法,都能使用这个方法获得hash值。
获取泛型类的类型参数
我们可以从以下代码获得提示,代码来自HashMap
,
这里的逻辑是获得类C
,然后获取它实现的接口Comparable<C>
,然后从这个Comparable<C>
中获得类型参数C
,然后比较这两个类型是否相等。虽然我们一直听说Java的泛型是类型擦除式,但是在这里我们是可以获得泛型的参数类型的。照例用一段demo测试一下,
sun.reflect.Reflection
这个工具类是和反射相关的,让大家知道有这么一个方法
我第一次见到这个方法是在java.sql.DriverManager
中的getConnection
方法中见到的
Reflection.getCallerClass()
是一个native
方法,返回的是Class<?>
类型,在DriverManager
中使用它的目的是为了获得相应的ClassLoader
,上面的代码是在Java 8中见到的。其中在Java 7中为获得ClassLoader
,DriverManager
就直接提供了native
的方法
我们用一段代码尝试调用这个方法
执行main方法会抛出异常
这个错误信息说的是我们缺少在函数调用栈开始位置添加CallerSensitive
注解,观察DriverManager
的getConnection
方法确实是有这么个注解的。
那如果给CalleeApp
的call
加上注解,那结果又会怎样呢?
Object.wait(long timeout, int nanos)
这个方法是来卖萌,它的本义在注释是这样子写的,
意思是提供精细化的时间衡量,nano
可是纳秒单位啊!!!
而它的实现却是这样的,
除了对传入参数的数值范围校验外,对nano
的使用紧紧是判断这个变量是否大于0,是则给timeout
加1,这只是增加了1毫秒的时间,并没有体现出了精细化的地方。
java.util.Base64
在此之前使用Base64工具可能需要引入apache commons等jar包,Java 8开始集成到JDK中了。
Base64
是单例模式,getEncoder
返回的是内部静态类Encoder
的静态成员RFC4648
,getDecoder
返回的是内部静态类Decoder
的静态成员RFC4648
;decode和encode当然是对应起来的,除此之外应该看到这样的写法值得学习,get方法中没有synchronized也没有去执行new等操作,所有需要的单例都是在类初始化的时候构造好的了。
附