Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java';谁在引擎盖下工作?_Java_Switch Statement - Fatal编程技术网

Java';谁在引擎盖下工作?

Java';谁在引擎盖下工作?,java,switch-statement,Java,Switch Statement,Java的switch语句是如何工作的?它如何将所使用变量的值与案例部分中给出的值进行比较?它使用的是=还是.equals(),还是完全其他的东西 我主要对1.7之前的版本感兴趣。如果使用1.7之前的Java,我假设它使用 == 因为对于int,例如不能使用equals,对于enum,equals和==将返回相同的结果 编辑 我的假设是错误的,它使用了可查找的字节码,如下所示: tableswitch 1.在Java7到来之前,它是“==”,因为我们可以使用整数和字符作为开关大小写,因为它们

Java的switch语句是如何工作的?它如何将所使用变量的值与案例部分中给出的值进行比较?它使用的是
=
还是
.equals()
,还是完全其他的东西


我主要对1.7之前的版本感兴趣。

如果使用1.7之前的Java,我假设它使用

==

因为对于int,例如不能使用equals,对于enum,equals和==将返回相同的结果

编辑

我的假设是错误的,它使用了可查找的字节码,如下所示:

 tableswitch

1.在
Java7
到来之前,它是
“==”
,因为我们可以使用整数和字符作为开关大小写,因为它们是原语,所以它必须是
“==”

2.
Java7
字符串也可以在开关大小写中使用,字符串作为
对象,使用
“.equals”


我想补充一下。。。
“==”
用于比较
对象引用
变量
而不是对象本身。使用
“.equals”
我们比较对象

如果您使用的是原语类型,例如整数,那么java将使用
=
来比较它们如果您使用的是字符串,那么java将使用
equals()
方法来测试字符串是否相等。如果将switch语句与enum一起使用,那么
=
equals()
都是相同的,所以使用哪一个并不重要。

正如您从中看到的,Java
switch
(至少在1.7之前)并不总是编译成
=
equals()
。相反,它使用表查找。虽然这是一个非常小的微观优化,但在进行大量比较时,表查找几乎总是更快

请注意,这仅用于检查密集键的
switch
语句。例如,检查枚举值的所有可能性可能会产生此主要实现(内部称为
tableswitch

如果检查更稀疏的密钥集,JVM将使用另一种系统,称为
lookupswitch
。相反,它将简单地比较各种键和值,对每种可能性进行优化的比较。为了说明这两种方法,请考虑下面两个开关语句:

switch (value1) {
case 0:
    a();
    break;
case 1:
    b();
    break;
case 2:
    c();
    break;
case 3:
    d();
    break;
}

switch (value2) {
case 0:
    a();
    break;
case 35:
    b();
    break;
case 103:
    c();
    break;
case 1001:
    d();
    break;
}
第一个示例很可能使用表查找,而另一个示例(基本上)使用比较

一个开关可以处理byte、short、char和int原语数据 类型。它也适用于枚举类型(在枚举类型中讨论), String类,以及一些包装特定 基本类型:字符、字节、短字符和整数。(Java 1.6)


原语与
=
进行比较时,
开关
方法肯定在Java 1.6(及更早版本)中使用了这种比较。

两者都没有。它使用JVM指令,这本质上是一种表查找。请看以下示例中的字节码:

public static void main(String... args) {
  switch (1) {
  case 1:
    break;
  case 2:
    break;
  }
}

public static void main(java.lang.String[]);
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   iconst_1
   1:   lookupswitch{ //2
                1: 28;
                2: 31;
                default: 31 }
   28:  goto    31
   31:  return
抄袭

在字节码中有两种形式的开关:表开关和查找开关。一个假设密钥集密集,另一个假设密钥集稀疏。请参阅JVM规范中编译开关的描述。对于枚举,找到序号,然后代码继续作为int大小写。我不完全确定JDK7中建议的开启字符串小功能将如何实现

然而,频繁使用的代码通常在任何合理的JVM中编译。乐观主义者并非完全愚蠢。不用担心,按照通常的启发式方法进行优化


您将在

中找到您感兴趣的Java版本的详细答案?在1.7中,switch也适用于字符串。在1.7之前,
switch
仅适用于枚举和原语,对于它们,
==
.equals
是同一回事。@LouisWasserman和装箱原语,所以这个问题仍然有意义。我想它对盒装原语没有特殊情况;它只是做了自动拆箱并使用了原语开关。一些谷歌搜索会出现,你能找到一个规范参考吗?切换情况条件是否可能使用既不是==,也不是.equals()的比较?@RaghavSood:如果没有某种比较运算符,您将如何比较两个基本体,更不用说对象了?我不明白在没有任何比较操作的情况下如何创建switch语句。@Makoto我不是说没有进行比较操作。我想问的是,是否有可能使用第三种,仅JVM的比较,这在我们访问的API中是不可用的。例如,不允许使用-1.7之前的整数。您应该编辑掉答案中不正确的部分,并且断言
tableswitch
不会比通常的if/else快很多,这是荒谬的。考虑一个带有几百个案例的<代码>开关>代码>语句。它是O(1)而不是O(N)。“等于和==”取决于切换变量的类型。或者int和chars是否转换为整数,Character?例如,不允许-1.7之前的整数。因此,我将重新表述我的注释:在java 7中,考虑到允许字符串作为switch语句中的变量,等式“运算符”可以是“==”或“.equals”,具体取决于切换变量的类型。或者,原语类型(int,char)是否封装在它们的包装中,为了统一起见,只使用“.equals”。在Java 7问世之前和之后,它都使用了
查找开关
表开关
,而不是
==
.equals()
。我认为这不是一个有效的答案。一个JVM使用该实现的事实