【java】java 局部变量表中的槽是可以重用的

在这里插入图片描述

1.概述

2.局部变量表

局部变量表(Local Variables Table)用来保存方法中的局部变量,以及方法参数。当 Java 源代码文件被编译成 class 文件的时候,局部变量表的最大容量就已经确定了

我们来看这样一段代码。

public class LocalVaraiablesTable {
    
    
    private void write(int age) {
    
    
        String name = "沉默王二";
    }
}

write() 方法有一个参数 age,一个局部变量 name。

然后用 Intellij IDEA 的 jclasslib 查看一下编译后的字节码文件 LocalVaraiablesTable.class。可以看到 write() 方法的 Code 属性中,Maximum local variables(局部变量表的最大容量)的值为 3。

在这里插入图片描述
按理说,局部变量表的最大容量应该为 2 才对,一个 age,一个 name,为什么是 3 呢?

当一个成员方法(非静态方法)被调用时,第 0 个变量其实是调用这个成员方法的对象引用,也就是那个大名鼎鼎的 this。调用方法 write(18),实际上是调用 write(this, 18)

点开 Code 属性,查看 LocalVaraiableTable 就可以看到详细的信息了。

在这里插入图片描述
第 0 个是 this,类型为 LocalVaraiablesTable 对象;第 1 个是方法参数 age,类型为整形 int;第 2 个是方法内部的局部变量 name,类型为字符串 String。

当然了,局部变量表的大小并不是方法中所有局部变量的数量之和,它与变量的类型和变量的作用域有关。当一个局部变量的作用域结束了,它占用的局部变量表中的位置就被接下来的局部变量取代了。

来看下面这段代码。

public static void method() {
    
    
    // ①
    if (true) {
    
    
        // ②
        String name = "沉默王二";
    }
    // ③
    if(true) {
    
    
        // ④
        int age = 18;
    }
    // ⑤
}
  • method() 方法的局部变量表大小为 1,因为是静态方法,所以不需要添加 this 作为局部变量表的第一个元素;

  • ②的时候局部变量有一个 name,局部变量表的大小变为 1;

  • ③的时候 name 变量的作用域结束;

  • ④的时候局部变量有一个 age,局部变量表的大小为 1;

  • ⑤的时候局 age 变量的作用域结束;

关于局部变量的作用域,《Effective Java》 中的第 57 条建议:

将局部变量的作用域最小化,可以增强代码的可读性和可维护性,并降低出错的可能性。

在此,我还有一点要提醒大家。为了尽可能节省栈帧耗用的内存空间,局部变量表中的槽是可以重用的,就像 method() 方法演示的那样,这就意味着,合理的作用域有助于提高程序的性能。

局部变量表的容量以槽(slot)为最小单位,一个槽可以容纳一个 32 位的数据类型(比如说 int,当然了,《Java 虚拟机规范》中没有明确指出一个槽应该占用的内存空间大小,但我认为这样更容易理解),像 float 和 double 这种明确占用 64 位的数据类型会占用两个紧挨着的槽。

来看下面的代码。

public void solt() {
    
    
    double d = 1.0;
    int i = 1;
}

用 jclasslib 可以查看到,solt() 方法的 Maximum local variables 的值为 4。

在这里插入图片描述
为什么等于 4 呢?带上 this 也就 3 个呀?

在这里插入图片描述
查看 LocalVaraiableTable 就明白了,变量 i 的下标为 3,也就意味着变量 d 占了两个槽。

在这里插入图片描述
此时知识联动了,赞 【Java】String 以及 StringTable 骨灰级 细节讲解 源码讲解 这里面有String的槽位。

M.参考

转载:携程面试官竟然问我 Java 虚拟机栈

猜你喜欢

转载自blog.csdn.net/qq_21383435/article/details/123647894
今日推荐