Unsafe类
简单讲一下这个类。Java无法直接访问底层操作系统,而是通过本地(native)方法来访问。不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作。
这个类尽管里面的方法都是public的,但是并没有办法使用它们,JDK API文档也没有提供任何关于这个类的方法的解释。总而言之,对于Unsafe类的使用都是受限制的,只有授信的代码才能获得该类的实例,当然JDK库里面的类是可以随意使用的。
从第一行的描述可以了解到Unsafe提供了硬件级别的操作,比如说获取某个属性在内存中的位置,比如说修改对象的字段值,即使它是私有的。不过Java本身就是为了屏蔽底层的差异,对于一般的开发而言也很少会有这样的需求。
举两个例子,比方说:
<span style="color:#000000"><code class="language-java"><span style="color:#000088">public</span> <span style="color:#000088">native</span> <span style="color:#000088">long</span> <span style="color:#009900">staticFieldOffset</span>(Field paramField);</code></span>
- 1
这个方法可以用来获取给定的paramField的内存地址偏移量,这个值对于给定的field是唯一的且是固定不变的。再比如说:
<span style="color:#000000"><code class="language-java"><span style="color:#000088">public</span> <span style="color:#000088">native</span> <span style="color:#000088">int</span> <span style="color:#009900">arrayBaseOffset</span>(Class paramClass);
<span style="color:#000088">public</span> <span style="color:#000088">native</span> <span style="color:#000088">int</span> <span style="color:#009900">arrayIndexScale</span>(Class paramClass);</code></span>
- 1
- 2
前一个方法是用来获取数组第一个元素的偏移地址,后一个方法是用来获取数组的转换因子即数组中元素的增量地址的。最后看三个方法:
<span style="color:#000000"><code class="language-java"><span style="color:#000088">public</span> <span style="color:#000088">native</span> <span style="color:#000088">long</span> <span style="color:#009900">allocateMemory</span>(<span style="color:#000088">long</span> paramLong);
<span style="color:#000088">public</span> <span style="color:#000088">native</span> <span style="color:#000088">long</span> <span style="color:#009900">reallocateMemory</span>(<span style="color:#000088">long</span> paramLong1, <span style="color:#000088">long</span> paramLong2);
<span style="color:#000088">public</span> <span style="color:#000088">native</span> <span style="color:#000088">void</span> <span style="color:#009900">freeMemory</span>(<span style="color:#000088">long</span> paramLong);</code></span>
- 1
- 2
- 3
分别用来分配内存,扩充内存和释放内存的。
当然这需要有一定的C/C++基础,对内存分配有一定的了解,这也是为什么我一直认为C/C++开发者转行做Java会有优势的原因。