public class Foo {
public static void main(String[] args) {
boolean flag = true;
if (flag) System.out.println("Hello, Java!");
if (flag == true) System.out.println("Hello, JVM!");
}
}
$ javac Foo.java $ java Foo Hello, Java! Hello, JVM!
# jasm与javap的输出比较类似 $ java -cp ./asmtools.jar org.openjdk.asmtools.jdis.Main Foo.class > Foo.jasm.bak
$ tail -n 23 Foo.jasm.bak | head -n 21
public static Method main:"([Ljava/lang/String;)V"
stack 2 locals 2
{
iconst_1;
istore_1;
iload_1;
ifeq L14; # 出栈int,如果等于0时跳转;实际为1,无需跳转
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Hello, Java!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
L14: stack_frame_type append;
locals_map int;
iload_1;
iconst_1;
if_icmpne L27; # 出栈2个int,如果不相等时跳转;实际为1和1,无需跳转
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Hello, JVM!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
L27: stack_frame_type same;
return;
}
使用awk命令修改字节码
$ awk 'NR==1,/iconst_1/{sub(/iconst_1/, "iconst_2")} 1' Foo.jasm.bak > Foo.jasm
$ tail -n 23 Foo.jasm.bak | head -n 21
public static Method main:"([Ljava/lang/String;)V"
stack 2 locals 2
{
iconst_2; # iconst_1 -> iconst_2
istore_1;
iload_1;
ifeq L14; # 出栈int,如果等于0时跳转;实际为1,无需跳转
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Hello, Java!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
L14: stack_frame_type append;
locals_map int;
iload_1;
iconst_1;
if_icmpne L27; # 出栈2个int,如果不相等时跳转;实际为1和2,需跳转
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Hello, JVM!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
L27: stack_frame_type same;
return;
}
$ java -cp ./asmtools.jar org.openjdk.asmtools.jasm.Main Foo.jasm $ java Foo Hello, Java!
private static String floatToHexIntBits(float f) {
return Integer.toHexString(Float.floatToIntBits(f));
}
float z1 = +0.0F; // +0.0F
float z2 = -0.0F; // -0.0F
log.info("{}", floatToHexIntBits(z1)); // 0
log.info("{}", floatToHexIntBits(z2)); // 0x80000000
log.info("{}", z1 == z2); // 两个0对应的内存数值不同,但+0.0F == -0.0F
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
log.info("{}", floatToHexIntBits(Float.POSITIVE_INFINITY)); // 0x7F800000
log.info("{}", floatToHexIntBits(Float.NEGATIVE_INFINITY)); // 0XFF800000
float f = 1.0F;
log.info("{}", floatToHexIntBits(NaN)); // 0x7FC00000
log.info("{}", NaN < f); // false
log.info("{}", NaN >= f); // false
log.info("{}", NaN != f); // true
log.info("{}", NaN == f); // false
log.info("{}", NaN == NaN); // false
@Slf4j
@Data
public class User {
private boolean sex;
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
User user = new User();
Field sexField = User.class.getDeclaredField("sex");
unsafe.putByte(user, unsafe.objectFieldOffset(sexField), (byte) 2);
log.info("{}", user.isSex()); // 10 -> 0 , false
unsafe.putByte(user, unsafe.objectFieldOffset(sexField), (byte) 3);
log.info("{}", user.isSex()); // 11 -> 1 , true
}
}
转载请注明出处:http://zhongmingmao.me/2018/12/15/jvm-basic-native-type/
访问原文「基本类型」获取最佳阅读体验并参与讨论