java中的基本数据类型与JVM中的基本数据类型

java是一门面向对象的语言,但是对于“基本数据类型”是特殊的。之所以java中引入基本数据类型,是因为通过执行效率以及内存使用来提高应用软件的性能。

//正常情况下
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!");
        }
    }
}
//异常情况
public class Foo {

    public static void main (String [] args){
        boolean flag = 2;//java编译无法通过
        if(flag){
            System.out.println("HELLO,JAVA!");
        }
        if(flag==true){
            System.out.println("HELLO,JVM!");
        }
    }
}

对于java语言本身来说,第一种情况是合法。因为java编译器定义的boolean类型只包括“true”“false”两种;

对于java虚拟机来说,两种情况都是合法的。因为编译器将boolean类型映射为整数类型,虚拟机都是可以识别的。只不过java编译器特殊化处理,将“true”映射为“1”,“false”映射为“0”(这也就是为什么java虚拟机定义得更加广泛)。

将上述两种情况下的java分别反编译为字节码,如下图:

//第一种情况  
public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_1
         1: istore_1
         2: iload_1
         3: ifeq          14
         6: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         9: ldc           #3                  // String HELLO,JAVA!
        11: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        14: iload_1
        15: iconst_1
        16: if_icmpne     27
        19: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        22: ldc           #5                  // String HELLO,JVM!
        24: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        27: return
      LineNumberTable:
        line 4: 0
        line 5: 2
        line 6: 6
        line 8: 14
        line 9: 19
        line 11: 27
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      28     0  args   [Ljava/lang/String;
            2      26     1  flag   Z
      StackMapTable: number_of_entries = 2
        frame_type = 252 /* append */
          offset_delta = 14
          locals = [ int ]
        frame_type = 12 /* same */

 执行结果:不用多说,大家都知道。

//第二种情况 
public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_2
         1: istore_1
         2: iload_1
         3: ifeq          14
         6: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         9: ldc           #1                  // String HELLO,JAVA!
        11: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        14: iload_1
        15: iconst_1
        16: if_icmpne     27
        19: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        22: ldc           #2                  // String HELLO,JVM!
        24: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        27: return
      StackMapTable: number_of_entries = 2
        frame_type = 252 /* append */
          offset_delta = 14
          locals = [ int ]
        frame_type = 12 /* same */

执行结果:只有 HELLO,JAVA!

从以上结果的不同,我们可以看出:

两个if语句的字节码指令有所不同-----ifeq与if_icmpne

ifeq代表:只要传入的参数不为"0",则继续执行,否则跳转;

if_icmpne代表:只有传入的参数为"1",才继续执行,否则跳转。

上述改变字节码可以通过asmtools工具来实现。

 

对于java基本数据类型的范围,如下图所示:

 从前面的boolean类型,我们可以看出,在java虚拟中,boolean类型可以定义为“0”“1”之外的整数类型,同样的,对于其他基本数据类型,也可以定义超出范围的数值。不过,在正常使用java编译器的话,这种情况是不会出现的。

除了基本数据类型的范围之外,还需要知道基本数据类型的大小。

在栈中,在32位hotspot虚拟机中,对于32位数据类型以内的数据类型:boolean/byte/short/char/reference/float/int占用4个字节,相当于1个slot,如果是64位数据类型:double/long的话,则占用2个slot;在64位hotspot虚拟机中,boolean/byte/short/char占用8个字节。

在堆中,基本数据类型boolean/byte/short/char分别占用1/1/2/2个字节。

存储:如果int类型的数值以这四种基本数据存储的话,则会进行掩码操作,因为这四种类型的长度不足以容纳int类型(8)。boolean类型比较特殊,因为boolean直接以byte存储的,但是又为了保证boolean在堆上的值是合法的,所以只取了最后一位来作为值进行存储。

加载:如果这四种基本数据类型加载到栈中的话,则在高位进行填充。

 

 

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页