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