Unsafe.putBoolean和Unsafe.puByte是native实现
putBoolean和putByte也是通过宏SET_FIELD模板出的函数
#define SET_FIELD(obj, offset, type_name, x) \
oop p = JNIHandles::resolve(obj); \
*(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x)
unsafe.cpp中定义宏做truncate
#define truncate_jboolean(x) ((x) & 1)
#define truncate_jbyte(x) (x)
#define truncate_jshort(x) (x)
#define truncate_jchar(x) (x)
#define truncate_jint(x) (x)
#define truncate_jlong(x) (x)
#define truncate_jfloat(x) (x)
#define truncate_jdouble(x) (x)
综上:unsafe.Put*不会对值做修改
------------------------------------------------------------------------------------
getBoolean和getByte也是通过宏GET_FIELD模板出的函数
#define GET_FIELD(obj, offset, type_name, v) \
oop p = JNIHandles::resolve(obj); \
type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
综上,unsafe.Get*不会对值做修改
------------------------------------------------------------------------------------
验证:
unsafe.putByte(foo, addr, (byte)2); // 设置为: 2
System.out.println(unsafe.getByte(foo, addr)); // 打印getByte: 2
System.out.println(unsafe.getBoolean(foo, addr)); // 打印getBoolean: true
unsafe.putByte(foo, addr, (byte)1); // 设置为: 1
System.out.println(unsafe.getByte(foo, addr)); // 打印getByte: 1
System.out.println(unsafe.getBoolean(foo, addr)); // 打印getBoolean: true
------------------------------------------------------------------------------------
疑问:
if(foo.flag)判断,使用getfield Field flag:"Z",执行逻辑等于:0 != flag
if(foo.getFlag())判断,使用invokevirtual Method getFlag:"()Z",执行逻辑等于: 0 != ((flag) & 1)
求大神帮忙解答
--------------------------
附getFlag jasm码:
public Method getFlag:"()Z"
stack 1 locals 1
{
aload_0;
getfield Field flag:"Z";
ireturn;
}
https://gist.github.com/qudongfang/49635d86882c03e49cff2b0f7d833805
展开
作者回复: 研究得非常深入!
Unsafe.putBoolean会做掩码,另外方法返回也会对boolean byte char short进行掩码