package jef.tools; import java.lang.reflect.Field; import junit.framework.TestCase; @SuppressWarnings("restriction") public class TestUnsafeSupport extends TestCase { private static sun.misc.Unsafe unsafe; private static BeanForTest person; long ageOffset; long nameOffset; long dateOffset; long arrayOffset; protected void setUp() throws Exception { Field field = null; try { field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (sun.misc.Unsafe) field.get(null); } catch (Exception ex) { ex.printStackTrace(); } person = new BeanForTest(); dateOffset = unsafe.objectFieldOffset(BeanForTest.class.getDeclaredField("date")); ageOffset = unsafe.objectFieldOffset(BeanForTest.class.getDeclaredField("age")); nameOffset = unsafe.objectFieldOffset(BeanForTest.class.getDeclaredField("name")); arrayOffset = unsafe.objectFieldOffset(BeanForTest.class.getDeclaredField("array")); } /** * 一般Reflection的操作java.lang.reflect.* */ public void testOrdinaryReflection() { try { Class<?> personClazz = BeanForTest.class; Field __ageField = personClazz.getDeclaredField("age"); assertEquals(0, __ageField.getInt(person)); __ageField.set(person, 5); assertEquals(5, __ageField.getInt(person)); } catch (Exception ex) { fail(ex.getLocalizedMessage()); } } /** * 测试sun.mic.Unsafe获取类Reflection以及初始化、修改对象状态等操作 * * */ public void testUnsafeReflection() { try { // 获取field在class定义中的位移位置 // getInt获取初始值 // 需要查看一下unsafe.getInt(long),确认这个long参数具体代表什么含义 // 经测试offset为参数的话,JVM异常 System.out.println(unsafe.getInt(person, ageOffset)); System.out.println(unsafe.getObject(person, ageOffset)); assertEquals(0, unsafe.getInt(person, ageOffset)); // cas // public native boolean compareAndSwapInt(Object obj, long offset, // int expect, int update); unsafe.compareAndSwapInt(person, ageOffset, 0, 25); unsafe.compareAndSwapInt(person, ageOffset, 12, 36);// 不等的情况下不会更新 assertEquals(25, unsafe.getInt(person, ageOffset)); unsafe.putInt(person, ageOffset, 0); assertEquals(0, unsafe.getInt(person, ageOffset)); // unsafe.putIntVolatile(); } catch (Exception ex) { ex.printStackTrace(); fail(ex.getLocalizedMessage()); } } }