我在Java程序中有几个switch
语句。我的问题是,如果我构造类似于此的switch
语句:
switch (getNum()) {
case 0: // do something
case 1: // do something
...
}
要从一个访问器方法(也就是'getter'方法)返回要切换的变量,每次检查一个case时switch语句都会调用getNum()
吗?或者它会为从int
返回的getNum()
分配一个临时变量来检查每个案例吗?
答案 0 :(得分:3)
每次检查一个case时,switch语句都会调用getNum()吗?
它根本不“检查每个案例”。它会对表达式进行一次计算,并根据实现情况通过几种技术之一立即跳转到相关案例。
或者它会为从getNum()返回的int分配一个临时变量来检查每个案例吗?
它也没有这样做:见上文。
答案 1 :(得分:2)
每次检查案例时,switch语句都会调用getNum()吗?或者它会为从getNum()返回的int分配一个临时变量来检查每种情况吗?
getNum()
表达式仅评估一次。有关语义的详细信息,请参阅JLS section 14.11
(事实上,一个switch语句通常被编译为不会针对每种情况测试值的代码。但这取决于案例的数量和范围,以及细节Java编译器。)
当你说“它会立即跳到案件中”时,你是什么意思?
(本机)机器代码级别的“技巧”是为不同的案例创建分支地址表。然后使用switch表达式的值索引到表中。在伪代码中它是这样的:
value = evaluate(expression)
branchAddress = switchTable[value]
jump(branchAddress)
如您所见,这避免了对value
进行一系列测试。但缺点是如果开关盒值的范围很大,你可能会得到一个大的开关表。因此,我的注意事项是:JIT编译器需要决定是以这种方式编译交换机还是作为一系列测试,或者使用这两种方法的组合。