美文网首页
Unsafe的一次使用

Unsafe的一次使用

作者: 哇_李荣 | 来源:发表于2018-08-18 16:48 被阅读0次

看LinkedHashMap源码的时候,不理解构造函数LinkedHashMap<String, String> lkMap = new LinkedHashMap<>(4, 0.75f, true);为什么要传三个参数。想着只传accessOrder不是就能达到目的了?接着想到运行时直接修改了accessOrder值也能达到目的。于是就写了下面这段代码。

        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        Unsafe unsafe = getUnsafe();
        Class c = map.getClass();
        Field f = c.getDeclaredField("accessOrder");
        long flong = unsafe.objectFieldOffset(f);
        unsafe.putBoolean(map, flong, true);
        map.put("tom", "apple");
        map.put("jerry", "orange");
        map.put("amy", "banana");
        map.get("jerry");
        map.put("james", "pear");
        map.forEach((o, v) -> System.out.println(o + "->" + v));

output:
    tom->apple
    amy->banana
    jerry->orange
    james->pear

使用默认构造函数创建map对象,再使用Unsafe方法访问map对象,修改accessOrder的取值。从输出结果看出,此时map记录的是访问顺序。相对的,如果没有修改accessOrder的话,上面的程序输出结果如下:

output:
    tom->apple
    jerry->orange
    amy->banana
    james->pear

输出内容是元素的插入顺序。

需要注意的是,官方不推荐使用Unsafe方法。如果直接调用Unsafe.getUnsafe()方法,会抛出java.lang.SecurityException异常。不过这个问题通过反射可以绕过。代码如下:

public static Unsafe getUnsafe() {
   try {
           Field f = Unsafe.class.getDeclaredField("theUnsafe");
           f.setAccessible(true);
           return (Unsafe)f.get(null);
   } catch (Exception e) { 
       /* ... */
   }
}

除了用上面的Unsafe类之外,用反射也能达到目的:

        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        Class c = map.getClass();
        Field f = c.getDeclaredField("accessOrder");
        f.setAccessible(true);
        f.set(map, true);

        map.put("tom", "apple");
        map.put("jerry", "orange");
        map.put("amy", "banana");
        map.get("jerry");
        map.put("james", "pear");
        map.forEach((o, v) -> System.out.println(o + "->" + v));

output:
    tom->apple
    amy->banana
    jerry->orange
    james->pear

相关文章

  • iOS内存管理

    __unsafe_unratained 修饰符的变量 使用__unsafe_unretained 使用的对象 必须...

  • Netty源码学习(6)--pipeline学习2

    Unsafe unsafe是不安全的意思,不要在应用程序里面直接使用Unsafe以及他的衍生类对象。Unsafe ...

  • Unsafe的一次使用

    看LinkedHashMap源码的时候,不理解构造函数LinkedHashMap lkMap = new Lin...

  • Java Unsafe CAS 小试

    Unsafe 在 Java 标准库和框架中被大量使用,本文主要介绍如何使用 sun.misc.Unsafe 包实现...

  • Java并发 - Unsafe与LockSupport

    1,Unsafe简介 1)通过Unsafe类可以分配、释放内存。如DirectByteBuffer底层使用unsa...

  • go常用包——unsafe

    unsafe 1 unsafe包简介 unsafe包顾名思义,是非安全的,是面向编译器的一个包,使用它要特别小心,...

  • 说说Java的Unsafe类

    本文主要内容 Unsafe类介绍 Unsafe的主要功能 总结 1、Unsafe类介绍 第一次看到这个类时被它的名...

  • Unsafe的使用解析

    相信很多人都阅读过jdk源码,这两天在看一段代码都时候正好用到Unsafe(JRE的rt.jar中提供了一个类su...

  • golang中的unsafe包详解

    一、unsafe 作用 从golang的定义来看,unsafe 是类型安全的操作。顾名思义,它应该非常谨慎地使用;...

  • java原子变量操作类以及实现原理分析

    java的原子变量操作类都是通过Unsafe的CAS方法实现。先看如何使用Unsafe实现原子自增。(有关Unsa...

网友评论

      本文标题:Unsafe的一次使用

      本文链接:https://www.haomeiwen.com/subject/ixvfiftx.html