首页 > 其他分享 >无题

无题

时间:2023-01-06 14:33:22浏览次数:55  
标签:case return int res 号位 break 无题

(以下测试均采用 hotspot 虚拟机)讨论两个问题:

finally

以下代码输出什么

import org.junit.Test;

public class NoneTest1 {

    public String code(){
        String str = "1";
        try {
            return str;
        }finally {
            str = "2";
        }
    }

    @Test
    public void test(){
        System.out.println(code());
    }

}

解释

switch

在空间允许的情况下,以下哪个test效率高

public class NoneTest2 {

    public int test1(int num){
        int res;
        switch (num){
            case 1:
                res = 1;
                break;
            case 2:
                res = 2;
                break;
            case 3:
                res = 3;
                break;
            default:
                res = 0;
        }
        return res;
    }

    public int test2(int num){
        int res;
        switch (num){
            case 1:
                res = 1;
                break;
            case 3:
                res = 3;
                break;
            case 2:
                res = 2;
                break;
            default:
                res = 0;
        }
        return res;
    }

    public int test3(int num){
        int res;
        switch (num){
            case 10:
                res = 10;
                break;
            case 30:
                res = 30;
                break;
            case 40:
                res = 40;
                break;
            default:
                res = 0;
        }
        return res;
    }

}

解释

解释

第一个问题

输出的是,并不会输出 2 ,原因在 oracle(此版本为jdk8) 官方已经给出来了

1

圈出来的一段的最后一句

# 如果 try 语句中包含return,则编译后的代码执行以下操作
If the try clause executes a return, the compiled code does the following:
# 保存返回值到局部变量表中
1.Saves the return value (if any) in a local variable.
# 执行 finally 代码
2.Executes a jsr to the code for the finally clause.
# 从 finally 返回时,返回保存在局部变量表中的值
3.Upon return from the finally clause, returns the value saved in the local variable.

所以在上方返回的是临时保存在局部变量表中的 str="1"

异常表

2

当字节码 3—5行出现异常时,直接跳转第 10 行

对应字节码

 0 ldc #2 <1>	#加载 “1” 到操作数栈
 2 astore_1		#保存到局部变量表 1 的位置(0位置是this)
 3 aload_1		#加载局部变量表 1 号位到操作数栈
 4 astore_2		#保存到 2 号位(对应上面第一句话,保存返回值到局部变量表中)
 5 ldc #3 <2>	#加载 “2” 到操作数栈
 7 astore_1		#保留给 1 号位,此时 1 号位为 “2”,2 号位依旧为1
 8 aload_2		#加载 2 号位
 9 areturn		#返回 2 号位
10 astore_3		#当出现异常时跳转到该位置,保存 异常 到 3 号位
11 ldc #3 <2>
13 astore_1
14 aload_3		#加载 3 号位异常
15 athrow		#抛出异常

所以可以看出在返回时做了一次复制操作,需要注意的是,如果返回的是对象,复制的是 对象地址值 ,而不是直接复制一份实例对象。

第二个问题

test1 和 test2 效率相同,都优于 test3

oracle switch 章节中,最后一句话说明了,在空间允许的情况下,tableswitch 更优于 lookupswitch

3

而要被编译成 tableswitch,The tableswitch instruction is used when the cases of the switch can be efficiently represented as indices into a table of target offsets.

当case可以有效的表示为目标偏移表中的索引时,采用tableswitch,简单来说,就是当 case 条件为连续的时候,采用 tableswitch,所以 test1、test2 会被编译成 tableswitch,虽然 test2 case条件并不是连续的,但是在编译的时候会进行排序然后采用 tableswitch。而 test3 采用的是 lookupswitch。

甚至存在如下代码采用的还是 tableswitch

public int test4(int num){
    int res;
    switch (num){
        case 1:
            res = 1;
            break;
        case 3:
            res = 3;
            break;
        case 4:
            res = 4;
            break;
        default:
            res = 0;
    }
    return res;
}

标签:case,return,int,res,号位,break,无题
From: https://www.cnblogs.com/ytryhard/p/17030380.html

相关文章

  • 无题——随感
    ​ 我以前一直也在等一个完美的时机,但后来我看到了一句名言告诉我世界上根本就没有一切就绪,在你斗志昂扬时偏偏是个阴天,作废;在你终于翻开课本认真学习时老妈突然要和你吵......
  • 无题
     青石板,花纸伞,袅袅炊烟出低檐,雨打乌篷船; 杨柳岸,水云间,绵绵寸山似墨染,古筝声飞雁。 斜街深巷白墙远,万千过客,谁人识少年? 湖中清莲相无言,一笑倾城,余生念江南。 ......
  • JavaScript之无题之让人烦躁的模块化
    我怎么记得我好像写过相关类型的文章,但是我找遍了我的博客没有~那就再写一遍吧,其实模块化的核心内容也算不上是复杂,只不过需要整理一下,规划一下罢了。嘻嘻。开始写......
  • 无题160226
    无题160226我一个人,不悲不喜只要不想你 我一个人,不愿悲伤我要不想你 关于你的词,还会继续你,也许不是你可是还会想起2016.2.26 整理以前的图片,偶然翻到。2015......
  • 无题
    你是否曾有过一张照片,带入云雾弥漫的梦里?是否有过一首歌,是深夜辗转反侧的陪伴?有些人注定只能陪你走过那最艰难的岁月,却不能在阳光正好微分不燥的时空出现。那些记忆深......